同時に検索される2つの文字列を持つ.txt拡張子がある場合とない場合のファイルのディレクトリを再帰的に検索したいと思います。この問題にどのように対処する必要がありますか?
たとえば、このディレクトリには、「String1」、「String2」、および「String3」を含む5つのファイルがあります。そのうちの2つは.pdfと.htmlですが興味はありません。残りの3つは.txtファイルまたは拡張子がありません。すべての文字列を含み、拡張子が.txtであるか、拡張子がまったくないパスを取得したいと思います。
ベストアンサー1
修正された質問で更新されました。
find directory -type f \( -name '*.txt' -o ! -name '*.*' \) \
-exec grep -q -F -e 'string 1' {} \; \
-exec grep -q -F -e 'string 2' {} \; \
-exec grep -q -F -e 'string 3' {} \; \
-print
これは、再帰的に呼び出されるディレクトリ内の名前にドットがない通常のファイルだけでなく、ファイル名のサフィックスを持つ一般的なdirectory
ファイルも検索します。.txt
そのようなファイルが見つかったら、grep
前に説明したのと同様の方法で、3つの文字列がすべてファイルに存在することを確認します(下記参照)。
文字列が見つかると、ファイルのパス名が印刷されます。
または、最初の部分(下)のコードを使用してください。
find directory -type f \( -name '*.txt' -o ! -name '*.*' \) -exec sh -c '
for pathname do
if grep -q -F -e "string 1" "$pathname" &&
grep -q -F -e "string 2" "$pathname" &&
grep -q -F -e "string 3" "$pathname"
then
printf "All were found in \"%s\"\n" "$pathname"
fi
done' sh {} +
また見なさい:
質問を修正する前の前の回答:
Unixはファイル名からファイルタイプを推測しないため、ファイル名は重要ではありません。
というファイルに特定の文字列があるかどうかをテストするには、file
次のようにします。
if grep -q -F -e 'some string' file; then
echo 'The string is present'
else
echo 'The string is not present'
fi
ここで使用されるオプションgrep
は
-q
:静かになりgrep
、パターンが一致するとすぐに終了します。パターンに一致する行を抽出するのではなく、一致が見つかったかどうかを反映する終了状態で終了します。この終了ステータスは上記の文で使用されていますif
。-F
:grep
パターンは正規表現ではなく文字列として扱われます。これにより、a * [in the] sky
同様の文字列がテキスト内の特殊文字をエスケープしなくてもテキストに表示されるかどうかをテストできます。-e
:grep
次の引数が一致パターンとして扱われます。これにより、コマンドラインオプションとして考える-
必要なく、で始まるパターンを使用できます。grep
複数の文字列をテストするには、grep
次のように追加のテストを追加します。
if grep -q -F -e 'string 1' file &&
grep -q -F -e 'string 2' file &&
grep -q -F -e 'string 3' file
then
echo 'All three string were found in the file'
else
echo 'One or more string was not found in the file'
fi
たとえば、名前付き配列を持つシェルを使用すると、配列bash
に文字列を格納し、次のループを実行することもできます。
strings=( 'string 1' 'string 2' 'string 3' )
found=true
for string in "${strings[@]}"; do
if ! grep -q -F -e "$string" file; then
found=false
break
fi
done
if "$found"; then
echo 'All strings were found'
else
echo 'Not all strings were found'
fi
これは文字列を繰り返し、そのうちの1つはいいえ検出(!
テスト結果を否定することに注意してくださいgrep
)し、変数をfound
設定してfalse
ループを終了します(追加の文字列をテストする必要はありません)。
$found
その後、それがまたはtrue
認知テストしfalse
、そのテスト結果に基づいてアクションを実行します。
上記のシェルコードは、次のように書き直されました/bin/sh
(名前付き配列なし)。
set -- 'string 1' 'string 2' 'string 3'
found=true
for string do
if ! grep -q -F -e "$string" file; then
found=false
break
fi
done
if "$found"; then
echo 'All strings were found'
else
echo 'Not all strings were found'
fi