grep 検索結果からスペースをエスケープするには? (ファイル名)

grep 検索結果からスペースをエスケープするには? (ファイル名)

私がこれを実行したとき:

for f in $(grep -r --include=*.directory "search-string"); do echo $f; done;

私が取得した検索結果は、検索結果ファイル名からスペースで区切られます。

grep 検索結果からスペースをエスケープするには?

ベストアンサー1

配列のファイルリストが必要で、bashシェル(バージョン4.4以降)を使用している場合は、次のことができます。

readarray -td '' files < <(
  grep -rlZ --include='*.directory' "search-string" .
)

シェルを含むzsh:

files=(${(0)"$(grep -rlZ --include='*.directory' "search-string" .)"})

以下を使用して繰り返します。

for file in "${files[@]}"; do
  printf '%s\n' "$file"
done

を使用すると、zsh次の方法で中間配列をスキップできます。

for file in ${(0)"$(grep -rlZ --include='*.directory' "search-string" .)"}; do
  printf '%s\n' "$file"
}

引用符のない単語拡張子($fまたは$(...))は非常に特別な意味を持ち、一般bash的に望むものではなく、ファイル名にはNULを除くすべてのバイト値を含めることができるため、表現するときにNULと言ってもかまいませ00。一意に区切られたファイルパスのリスト区切りのバイトストリームとして使用するのは安全です。これがGNUの-Z/オプションの目的です。--nullgrep

次の単純なシェルでは、GNUの出力を使用してシェルが参照するファイル名のリストを生成し、シェルコードで評価dashできます。gawkgrepsh

eval set -- "$(
  grep -rlZ --include='*.directory' "search-string" . |
    gawk -v RS='\0' -v ORS=' ' -v q="'" '
      {gsub(q, q "\\" q q); print q $0 q}'
)"

for file do
  printf '%s\n' "$file"
done

ファイル名に改行文字が含まれていないことを保証できる場合は、次のように単純化できます。

IFS='
'
set -o noglob

for file in $(grep -rl --include='*.directory' "search-string" .); do
  printf '%s\n' "$file"
done

set -o noglobファイル名に*、、、(シェルおよびシェルのバージョンによって、およびより多くのglob演算子)も含まれていない?ことを保証できればスキップできます。[\

おすすめ記事