使用 GREP 搜索文件的特定行

ati*_*tin 2 linux bash terminal grep command-line-interface

我有一个包含许多文本文件的目录。我想在文件的特定行中搜索给定的字符串(例如仅在每个文件的第 2 行和第 3 行中搜索“abc”)。然后当我找到匹配项时,我想打印匹配文件的第 1 行。

我的方法 - 我正在使用 -n 选项进行 grep 搜索并将输出存储在不同的文件中,然后在该文件中搜索行号。然后我试图获取文件名,然后打印出它的第一行。

使用我上面提到的方法,我无法获得正确文件的文件名,即使我知道这种方法非常冗长。

有没有更好更快的解决方案?

例如。
1.txt

file 1
one
two
Run Code Online (Sandbox Code Playgroud)

2.txt

file 2
two
three
Run Code Online (Sandbox Code Playgroud)

我想在每个文件grep的第 2 行中搜索“两个” ,然后使用匹配打印文件的第一行。在这个例子中,这将是 2.txt,输出应该是“文件 2”

我知道使用sed/更容易,awk但是有什么方法可以使用grep吗?

Tho*_*hor 6

使用sed替代(GNU SED):

解析.sed

1h                 # Save the first line to hold space
2,3 {              # On lines 2 and 3
  /my pattern/ {   # Match `my pattern`
    x              # If there is a match bring back the first line
    p              # and print it
    :a; n; ba      # Loop to the end of the file
  }
}
Run Code Online (Sandbox Code Playgroud)

像这样运行它:

sed -snf parse.sed file1 file2 ...
Run Code Online (Sandbox Code Playgroud)

或者作为单线:

sed -sn '1h; 2,3 { /my pattern/ { x; p; :a; n; ba; } }' file1 file2 ...
Run Code Online (Sandbox Code Playgroud)

您可能还想发出文件名,例如使用您的示例数据:

解析2.sed

1h                 # Save the first line to hold space
2,3 {              # On lines 2 and 3
  /two/ {   # Match `my pattern`
    F              # Output the filename of the file currently being processed
    x              # If there is a match bring back the first line
    p              # and print it
    :a; n; ba      # Loop to the end of the file
  }
}
Run Code Online (Sandbox Code Playgroud)

像这样运行它:

sed -snf parse2.sed file1 file2 | paste -d: - -
Run Code Online (Sandbox Code Playgroud)

输出:

file1:file 1
file2:file 2
Run Code Online (Sandbox Code Playgroud)


Sun*_*eep 6

$ awk 'FNR==2{if(/one/) print line; nextfile} FNR==1{line=$0}' 1.txt 2.txt
file 1

$ awk 'FNR==2{if(/two/) print line; nextfile} FNR==1{line=$0}' 1.txt 2.txt
file 2
Run Code Online (Sandbox Code Playgroud)
  • FNR 将具有正在读取的当前文件的行号
    • 使用FNR>=2 && FNR<=3,如果你需要一个行范围
  • FNR==1{line=$0} 将保存第一行的内容以备将来使用
  • nextfile 大多数实现都应该支持,但是如果您需要删除它,该解决方案仍然可以工作(虽然速度较慢)