54

私はしばしば次のようなコマンドを書きたいと思います (zsh関連する場合は で):

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

(または grep のより複雑な組み合わせ)

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

find <somebasedirectory> -print0 | xargs -0 dosomecommand

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

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

4

6 に答える 6

55

GNU Grep の--nullフラグを使用する

GNU Grepのドキュメントによると、 Output Line Prefix Control を使用して、 findxargsと同じ方法で ASCII NUL 文字を処理できます。

-Z
--null
通常ファイル名に続く文字の代わりにゼロバイト (ASCII NUL 文字) を出力します。たとえば、「grep -lZ」は、通常の改行ではなく、各ファイル名の後にゼロ バイトを出力します。このオプションは、改行などの特殊な文字を含むファイル名が存在する場合でも、出力を明確にします。このオプションは、'find -print0'、'perl -0'、'sort -z'、'xargs -0' などのコマンドで使用して、改行文字を含むファイルであっても、任意のファイル名を処理できます。

trGNU Coreutils から使用

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

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

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

于 2013-04-13T14:57:19.527 に答える
8

すでに GNUfindを使用しているため、これらの代わりに内部の正規表現パターン マッチング機能を使用できますgrep

find <somebasedirectory> -regex ".*stringinfilenamesIwant.*" ! -regex ".*stringinfilesnamesIdont.*" -exec dosomecommand {} + 
于 2013-04-12T19:43:45.050 に答える
3

GNU grep ソースの最新バージョンでは、-z/--nullを使用して出力をヌル文字で区切ることができるようになりましたが、以前は-l以下と組み合わせてのみ機能していました。

http://git.savannah.gnu.org/cgit/grep.git/commit/?id=cce2fd5520bba35cf9b264de2f1b6131304f19d2

これは、最新バージョンを使用すると、問題が自動的に解決されることを意味します。

于 2016-03-18T17:11:56.887 に答える