web-dev-qa-db-ja.com

findの-print0およびxargsの-0スイッチに相当するgrepはありますか?

私はよくこのようなコマンドを書きたいと思っています(関連する場合、zshに):

find <somebasedirectory> | \
    grep stringinfilenamesIwant | \
    grep -v stringinfilesnamesIdont | \
    xargs dosomecommand

(またはもっと複雑なgrepsの組み合わせ)

近年、find-print0スイッチが追加され、xargsに-0が追加されました。これにより、名前にスペースが含まれるファイルを、代わりにファイル名をnullで終了することでエレガントに処理できます。これを可能にする:

find <somebasedirectory> -print0 | xargs -0 dosomecommand

しかし、grep(少なくとも私が持っているバージョン、GNU Ubuntuでのgrep 2.10)は、消費に相当するものがないようですand nullを生成します-終端ライン; --nullがありますが、これは-lを使用してgrepで直接ファイルを検索するときに名前を出力することに関連しているようです。

Grepで使用できる同等のオプションまたはオプションの組み合わせはありますか?または、findの-regex、またはおそらくPerlを使用してコマンドのパイプを表現する簡単でエレガントな方法はありますか?

42
Andrew Ferrier

GNU Grep's --nullフラグを使用

GNU Grepドキュメント によると、出力行プレフィックス制御を使用して、ASCII NUL文字をfindおよび-と同じ方法で処理できます。 xargs

-Z
- ヌル
通常ファイル名の後に続く文字の代わりにゼロバイト(ASCII NUL文字)を出力します。たとえば、 'grep -lZ'は各ファイルの後にゼロバイトを出力します通常の改行の代わりに名前を指定します。このオプションは、改行などの異常な文字を含むファイル名が存在する場合でも、出力を明確にします。このオプションは、「find -print0」、「Perl -0」、「sort- z 'および' xargs -0 'は、改行文字を含む場合でも、任意のファイル名を処理します。

GNU Coreutilsからtrを使用します

OPが正しく指摘するように、このフラグは入力または出力でファイル名を処理するときに最も役立ちます。実際にgrep出力を変換してNUL文字を行末として使用するには、sedまたはtrのようなツールを使用して、出力の各行を変換する必要があります。例えば:

find /etc/passwd -print0 |
    xargs -0 egrep -Z 'root|www' |
    tr "\n" "\0" |
    xargs -0 -n1

このパイプラインはNULを使用してファイル名をfindから分離し、改行をegrepによって返される文字列のNULに変換します。これにより、NULで終了する文字列がパイプラインの次のコマンドに渡されます。この場合はxargsが出力を通常の文字列に戻しますが、何でもかまいません。

43
Todd A. Jacobs