簡體   English   中英

使用 GREP 搜索特定行的文件

[英]Searching specific lines of files using GREP

我有一個包含許多文本文件的目錄。 我想在文件的特定行中搜索給定的字符串(例如僅在每個文件的第 2 行和第 3 行中搜索“abc”)。 然后,當我找到匹配項時,我想打印匹配文件的第 1 行。

我的方法 - 我正在使用 -n 選項進行 grep 搜索並將 output 存儲在不同的文件中,然后在該文件中搜索行號。 然后我試圖獲取文件名,然后打印出它的第一行。

使用我上面提到的方法我無法獲得正確文件的文件名,即使我知道這種方法非常冗長。

對此有更好更快的解決方案嗎?

例如。
1.txt

file 1
one
two

2.txt

file 2
two
three

我想使用grep在每個文件的第 2 行中搜索“two”,然后使用匹配打印文件的第一行。 在這個例子中是 2.txt 而 output 應該是“文件 2”

我知道使用sed / awk更容易,但是有沒有辦法使用grep來做到這一點

使用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
  }
}

像這樣運行它:

sed -snf parse.sed file1 file2 ...

或者作為單線:

sed -sn '1h; 2,3 { /my pattern/ { x; p; :a; n; ba; } }' file1 file2 ...

您可能還想發出文件名,例如您的示例數據:

解析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
  }
}

像這樣運行它:

sed -snf parse2.sed file1 file2 | paste -d: - -

Output:

file1:file 1
file2:file 2
$ 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
  • FNR將具有當前正在讀取的文件的行號
    • 如果需要一系列行,請使用FNR>=2 && FNR<=3
  • FNR==1{line=$0}會保存第一行的內容以備后用
  • 大多數實現都應該支持nextfile ,但如果您需要刪除它,該解決方案仍然有效(雖然速度較慢)

使用grepbash

# Grep for a pattern and print filename and line number
grep -Hn one file[12] |        

# Loop over matches where f=filename, n=match-line-number and s=matched-line
while IFS=: read f n s; do 

  # If match was on line 2 or line 3
  # print the first line of the file
  (( n == 2 || n == 3 )) &&  head -n1 $f
done

Output:

file 1

僅使用grepcut| (管道):

grep -rnw pattern dir | grep ":line_num:" | cut -d':' -f 1

解釋

grep -rnw pattern dir

它返回找到模式的文件的名稱以及行號。 它是 output 會是這樣的

path/to/file/file1(.txt):8:some pattern 1
path/to/file/file2(.txt):4:some pattern 2
path/to/file/file3(.txt):2:some pattern 3

現在我正在使用另一個grep來獲取具有正確行號的文件(例如包含第 2 行模式的文件)

grep -rnw pattern dir | grep ":2:"

它的 output 將是

path/to/file/file3(.txt):2:line

現在我正在使用 cut 來獲取文件名

grep -rnw pattern dir | grep ":2:" | cut -d':' -f 1

它將 output 這樣的文件名

path/to/file/file3(.txt)

PS - 如果您想從文件名中刪除“path/to/file/”,您可以使用rev然后cut並再次rev ,您可以自己嘗試或查看下面的代碼。

grep -rnw pattern dir | grep ":2:" | cut -d':' -f 1 | rev | cut -d'/' -f 1 | rev

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM