从任意位置包含两个字符串的文件中提取所有行

从任意位置包含两个字符串的文件中提取所有行

我有一个 .txt 文件,其内容与此类似:

  • 100 150 180 200 300 400
  • 100 200 250 350 380 400
  • 100 160 170 400 450 500
  • 100 120 140 160 180 200
  • 100 120 140 160 180 300

我想抓取所有行,从任意位置包含“100”和“200”的特定列(如 2、3 或任何其他列)开始,然后将其输出到另一个单独的 txt 文件。我怎样才能做到这一点?在上面的例子中,正确的打印应该是:

  • 100 150 180 200 300 400
  • 100 200 250 350 380 400
  • 100 120 140 160 180 200

我尝试过使用 sublime 的“查找全部”功能,然后使用行尾的右箭头来突出显示它们,但不幸的是,有些行比其他行长得多,所以它不起作用。

答案1

$ grep 100 <file | grep 200 >newfile
$ cat newfile
100 150 180 200 300 400
100 200 250 350 380 400
100 120 140 160 180 200

第一个grep从原始文件中提取包含字符串 的所有行100。第二个grep提取所有行从那个结果包含字符串200.

请注意,这还会提取包含1100和等字符串的行,1200因为这些行包含所需的字符串作为子字符串。为了避免这种情况,请grep与它的-w选项一起使用(如果可用)。


要仅从特定列开始进行测试,请使用一个简短的awk程序:

$ awk -v col=1 '{ delete c; for (i=col; i<=NF; ++i) ++c[$i]; if (c[100] > 0 && c[200] > 0) print }' <file >newfile
$ cat newfile
100 150 180 200 300 400
100 200 250 350 380 400
100 120 140 160 180 200

awk程序从命令行获取变量的值col(此处值为 1)。然后,它从列开始遍历每个输入行col,计算每个值出现的次数。如果值100200出现超过零次,则打印该行。

该程序具有更好的布局:

{
    delete c

    for (i=col; i<=NF; ++i)
        ++c[$i]

    if (c[100] > 0 && c[200] > 0)
        print
}

该程序还适合使用以下命令提取行具体的某些项目的匹配数。

答案2

如果您确定不会出现误报,也可以尝试一下

awk '{TMP = $0; sub ($1 FS $2, "")} /100/ && /200/ {print TMP} ' file

相关内容