如果存在某个子字符串,则从文件中提取行

Extracting lines from a file if a certain substring is present

我有一个如下所示的文件:

Stef     NY       ID=1;CITY=NY
John     SE       ID=0;CITY=SE
Stef     SE       ID=2;CITY=SE

我只想提取第三列中 ID 大于 1 的那些行,因此预期输出变为:

Stef     SE       ID=2;CITY=SE

我负责删除 ID=1 或 ID=0 的 bash 脚本,但我不知道如何一起删除。这是我的:

awk ' !~ /^ID=1;/' file.txt > output.txt

但这给了我一个输出:

John     SE       ID=0;CITY=SE
Stef     SE       ID=2;CITY=SE

如何在上面的 bash 语句中添加 ID=0?将不胜感激。

该表达式是正则表达式,因此您可以使用:

awk ' !~ /^ID=[01];/' file.txt > output.txt

它有点脆弱,但你可以试试:

$ cat input
Stef     NY       ID=1;CITY=NY
John     SE       ID=0;CITY=SE
Stef     SE       ID=2;CITY=SE
$ awk '>1' FS='[=;]' input
Stef     SE       ID=2;CITY=SE

也就是说,拆分 =; 上的行,以便您要比较的数字位于字段 2 中。

这是一种通过从最后一个字段中删除所有不需要的字符来进行数值比较的方法:

awk '{val=$NF; gsub(/(^|.*;)ID=|;.*/, "", val)} val+0 > 1' file

Stef     SE       ID=2;CITY=SE

这对于这样的输入也能正常工作:

Stef     NY       ID=1;CITY=NY
Stef     NY       ID=01;CITY=NY
John     SE       ID=0;CITY=SE
Stef     SE       ID=2;CITY=SE
Stef     SE       ID=04;CITY=SE

awk ' !~ /^ID=1;/' file.txt > output.txt

工作原理

您的 AWK 命令(引号之间的任何内容)就像过滤器一样工作。

  • !~ // 按条件过滤第 3 个字段 (</code>)。条件是<strong>不匹配</strong>(<code>!~)正则表达式(在斜线//之间)。

^ID=1; 是匹配所有行 以 (^) ID=1.

开头的正则表达式

调整正则表达式

一样,您可以简单地更改常量文字模式 ID=1 以获得更灵活的模式,例如:

  • ID=[01]; ID 可以是 character-set 中的任何字符(方括号 [] 内的集合),因此 0 或 1
  • 定义为范围的相似集:ID=[0-1];(从 0 到 1)
  • 甚至不同的替代方案 ID=(0|1); 而替代方案列在一组中(括在括号内),由竖线符号分隔(| 通常表示逻辑或)

以上将匹配2个案例。

awk 的另一种可能性是:

awk '$NF ~ /^ID=[[:digit:]]+/ {split($NF,a,/=|;/);if (a[1]=="ID" && a[2] > 1) print [=10=]}' file
Stef     SE       ID=2;CITY=SE
  • 初始条件:仅当最后一个字段以序列开头 正则表达式的字符数 /^ID=[[:digit:]]+/
  • action:用分隔符=;拆分字段,然后检查条件(a[1]=="ID" && a[2] > 1)如果为真,打印当前行。