Bash

bash 查找以字元串開頭的行

  • March 27, 2014

我有一堆文件,我想找到哪個文件包含以某個字元串開頭的連續行。

例如對於以下文件:

Aaaaaaaaaaaa
Baaaaaaaaaaa
Cxxxxxxxxx
Cyyyyyyyyy
Czzzzzzzzz
Abbbbbbbbbbb
Bbbbbbbbbbbb
Caaaaaa
Accccccccccc
Bccccccccccc
Cdddddd
Ceeeeee

有不止一行以“C”開頭,所以我希望通過命令找到這個文件。

例如對於以下文件:

Aaaaaaaaaaaa
Baaaaaaaaaaa
Cxxxxxxxxx
Abbbbbbbbbbb
Bbbbbbbbbbbb
Caaaaaa
Accccccccccc
Bccccccccccc
Cdddddd

總是有一行以“C”開頭,我不想要這個文件。我想過使用 agrep或 ased但我不知道該怎麼做。也許使用正則表達式^C.*$^C或類似的東西。任何的想法 ?

pcregrep

pcregrep -rMl '^C.*\nC' .

POSIXly:

find . -type f -exec awk '
 FNR==1 {last=0; printed=0; next}
 printed {next}
 /^C/ {if (last) {print FILENAME; printed=1; nextfile} else last=1; next}
 {last=0}' {} +

(儘管這意味著使用那些awk不支持的實現完全讀取所有文件nextfile)。


使用 GNUgrep最高 2.5.4 的版本:

grep -rlP '^C.*\nC' .

似乎有效,但這是偶然的,不能保證有效。

在它在 2.6 中被修復之前(通過這個送出),GNUgrep忽略了它正在使用的 pcre 搜尋函式將匹配目前處理的整個緩衝區grep,從而導致各種令人驚訝的行為。例如:

grep -P 'a\s*b'

將匹配包含以下內容的文件:

bla
bla

這將匹配:

printf '1\n2\n' | grep -P '1\n2'

但是這個:

(printf '1\n'; sleep 1; printf '2\n') | grep -P '1\n2'

或者:

(yes | head -c 32766; printf '1\n2\n') > file; grep -P '1\n2' file

不會(因為1\n2\n是跨兩個由 處理的緩衝區grep)。

不過,這種行為最終被記錄在案:

15-如何跨行匹配?

標準 grep 無法做到這一點,因為它基本上是基於行的。因此,僅使用 '

$$ :space: $$’ 字元類與您可能期望的方式不匹配換行符。但是,如果您的 grep 是在啟用 Perl 模式的情況下編譯的,則可以使用 Perl ’s’ 修飾符(它使 ‘.’ 匹配換行符):

     printf 'foo\nbar\n' | grep -P '(?s)foo.*?bar'

在 2.6 中修復後,文件沒有修改(我曾經在那里報告過)。

引用自:https://unix.stackexchange.com/questions/121355