複数のファイルがあり、どのファイルに特定の文字列で始まる連続行が含まれているかを探したいと思います。
たとえば、次のファイルの場合:
Aaaaaaaaaaaa
Baaaaaaaaaaa
Cxxxxxxxxx
Cyyyyyyyyy
Czzzzzzzzz
Abbbbbbbbbbb
Bbbbbbbbbbbb
Caaaaaa
Accccccccccc
Bccccccccccc
Cdddddd
Ceeeeee
「C」で始まる行が2つ以上あるので、コマンドでファイルを検索したいと思います。
たとえば、次のファイルの場合:
Aaaaaaaaaaaa
Baaaaaaaaaaa
Cxxxxxxxxx
Abbbbbbbbbbb
Bbbbbbbbbbbb
Caaaaaa
Accccccccccc
Bccccccccccc
Cdddddd
常に「C」で始まる行があり、このファイルは必要ありません。私はagrep
またはaを使用しようとしましたが、sed
正確に何をすべきかわかりません。たぶん正規表現^C.*$^C
やそれに似たものを使うことができます。どんなアイデアがありますか?
ベストアンサー1
そしてpcregrep
:
pcregrep -rMl '^C.*\nC' .
POSIX的に:
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
)。
GNUバージョンgrep
最大2.5.4:
grep -rlP '^C.*\nC' .
現れるそれはうまくいきますが、これは失敗であり、動作は保証されません。
2.6で修正される前(今回提出してください)、GNUはgrep
使用中の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
で処理する 2 つのバッファにまたがっているためですgrep
)。
ただし、この動作は最終的に次のように文書化されました。
15行全体を一致させる方法は?
標準のgrepはデフォルトではラインベースなので、これはできません。したがって、 '[:space:]' 文字クラスを使用するだけでは、予想通り改行文字と一致しません。ただし、Perlモードが有効な状態でgrepがコンパイルされている場合は、Perl 's'修飾子を使用できます( '.'が改行と一致するようにします)。
printf 'foo\nbar\n' | grep -P '(?s)foo.*?bar'
2.6 修正後の文書は修正されていません。そこ)。