链 awk 正则表达式匹配像 grep
Chain awk regex matches like grep
我正在尝试使用 awk select/remove 基于 CSV 文件中的单元格条目的数据。
如何链接 Awk 命令来构建复杂的搜索,就像我在 grep
中所做的那样?我计划根据多列单元格中的匹配条件使用 Awk select 行,而不仅仅是本例中的第一列。
测试数据
123,line1
123a,line2
abc,line3
G-123,line4
G-123a,line5
将 Awk 语句与中间文件分开
awk ' !~ /^[[:digit:]]/ {print [=11=]}' file.txt > output1.txt
awk ' !~ /^G-[[:digit:]]/ {print [=11=]}' output1.txt > output2.txt
mv output2.txt output.txt
cat output.txt
链接或多行 grep
版本(我认为仅限于第一列)
grep -v \
-e "^[[:digit:]]" \
-e "^G-[[:digit:]]" \
file.txt > output.txt
cat output.txt
如何重写 Awk 命令以避免中间文件?
您可以使用
awk ' !~ /^(G-)?[[:digit:]]/' file.txt > output.txt
awk
尝试在字段 1 中查找:
^
- 字符串开头
(G-)?
- 一个可选的 G-
字符序列(注意 awk
中的正则表达式风格是 POSIX ERE,因此 (...)
表示捕获组并且?
表示 一次或零次 量词)
[[:digit:]]
- 一个数字。
如果找到匹配项,则不打印记录(=行)。否则,打印该行。
在您的 awk 命令和示例中,awk 认为 file.txt 只有一个字段,因为您没有定义 FS,因此使用默认的空白字段分隔符。
话虽如此,您可以像这样轻松地将两个模式匹配在一起:
awk '( !~ /^[[:digit:]]/) && ( !~ /^G-[[:digit:]]/) {print [=10=]}' file.txt
要使awk 使用逗号作为字段分隔符,您可以在BEGIN 块中定义它。在这个例子中,输出应该只是 line3
awk 'BEGIN {FS=","} ( !~ /^[[:digit:]]/) && ( !~ /^G-[[:digit:]]/) {print }' file.txt
通常,在 awk 中有可用的布尔运算符(它比 grep 更好!:))
awk '/match1/ || /match2/' file
awk '(/match1/ || /match2/ ) && /match3/' file
等等...
在您的示例中,您可以使用类似的东西:
awk -F, ' ~ /^[[:digit:]]/ || ~ /G-[[:digit:]]/' input >> output
注意:这只是一个如何使用布尔运算符的示例。也可以在这里使用正则表达式本身来表达替代匹配:
awk -F, ' ~ /^(G-)?[[:digit:]]/' input >> ouput
为了坚持你的问题,我会使用:
awk ' !~ /^[[:digit:]]/ && !~ /G-[[:digit:]]/' file.txt > output.txt
但我喜欢@Wiktor Stribiżew REGEX 方法!
我建议 awk 中那个 grep 命令的字面翻译是
awk '
/^[[:digit:]]/ {next}
/^G-[[:digit:]]/ {next}
{print}
' file.txt
但是你有几个例子可以说明如何写得更简洁。
使用您展示的示例,这也可以在 grep
中在单个正则表达式中完成,我们不需要链接不同的正则表达式,添加此解决方案以防 you/anyone 需要它;可能会有帮助。
grep -v -E '^(G-)?[[:digit:]]' Input_file
解释: 简单的解释是,使用 grep
的 -v
选项来省略那些行匹配上述模式。然后使用它的 -E
选项启用 ERE(扩展正则表达式)。在主程序中使用正则表达式 ^(G-)?[[:digit:]]
匹配如果行从 G- OR 数字开始然后不打印该行。
我正在尝试使用 awk select/remove 基于 CSV 文件中的单元格条目的数据。
如何链接 Awk 命令来构建复杂的搜索,就像我在 grep
中所做的那样?我计划根据多列单元格中的匹配条件使用 Awk select 行,而不仅仅是本例中的第一列。
测试数据
123,line1
123a,line2
abc,line3
G-123,line4
G-123a,line5
将 Awk 语句与中间文件分开
awk ' !~ /^[[:digit:]]/ {print [=11=]}' file.txt > output1.txt
awk ' !~ /^G-[[:digit:]]/ {print [=11=]}' output1.txt > output2.txt
mv output2.txt output.txt
cat output.txt
链接或多行 grep
版本(我认为仅限于第一列)
grep -v \
-e "^[[:digit:]]" \
-e "^G-[[:digit:]]" \
file.txt > output.txt
cat output.txt
如何重写 Awk 命令以避免中间文件?
您可以使用
awk ' !~ /^(G-)?[[:digit:]]/' file.txt > output.txt
awk
尝试在字段 1 中查找:
^
- 字符串开头(G-)?
- 一个可选的G-
字符序列(注意awk
中的正则表达式风格是 POSIX ERE,因此(...)
表示捕获组并且?
表示 一次或零次 量词)[[:digit:]]
- 一个数字。
如果找到匹配项,则不打印记录(=行)。否则,打印该行。
在您的 awk 命令和示例中,awk 认为 file.txt 只有一个字段,因为您没有定义 FS,因此使用默认的空白字段分隔符。
话虽如此,您可以像这样轻松地将两个模式匹配在一起:
awk '( !~ /^[[:digit:]]/) && ( !~ /^G-[[:digit:]]/) {print [=10=]}' file.txt
要使awk 使用逗号作为字段分隔符,您可以在BEGIN 块中定义它。在这个例子中,输出应该只是 line3
awk 'BEGIN {FS=","} ( !~ /^[[:digit:]]/) && ( !~ /^G-[[:digit:]]/) {print }' file.txt
通常,在 awk 中有可用的布尔运算符(它比 grep 更好!:))
awk '/match1/ || /match2/' file
awk '(/match1/ || /match2/ ) && /match3/' file
等等...
在您的示例中,您可以使用类似的东西:
awk -F, ' ~ /^[[:digit:]]/ || ~ /G-[[:digit:]]/' input >> output
注意:这只是一个如何使用布尔运算符的示例。也可以在这里使用正则表达式本身来表达替代匹配:
awk -F, ' ~ /^(G-)?[[:digit:]]/' input >> ouput
为了坚持你的问题,我会使用:
awk ' !~ /^[[:digit:]]/ && !~ /G-[[:digit:]]/' file.txt > output.txt
但我喜欢@Wiktor Stribiżew REGEX 方法!
我建议 awk 中那个 grep 命令的字面翻译是
awk '
/^[[:digit:]]/ {next}
/^G-[[:digit:]]/ {next}
{print}
' file.txt
但是你有几个例子可以说明如何写得更简洁。
使用您展示的示例,这也可以在 grep
中在单个正则表达式中完成,我们不需要链接不同的正则表达式,添加此解决方案以防 you/anyone 需要它;可能会有帮助。
grep -v -E '^(G-)?[[:digit:]]' Input_file
解释: 简单的解释是,使用 grep
的 -v
选项来省略那些行匹配上述模式。然后使用它的 -E
选项启用 ERE(扩展正则表达式)。在主程序中使用正则表达式 ^(G-)?[[:digit:]]
匹配如果行从 G- OR 数字开始然后不打印该行。