次のような文字列があります。"thisissometext"
この文字列、または途中に空白や改行が含まれるこの文字列のバリエーションを含む、特定のディレクトリ内のすべてのテキスト ファイルを (再帰的に) 検索します。たとえば、、"this is sometext"
または"this\n issometext"
、を含むテキスト ファイル"this\n isso metext"
が検索に表示されるはずです。これはどのように実行できますか?
答え1
新しいバージョンの GNU grep
(オプションあり-z
) では、次のワンライナーを使用できます。
find . -type f -exec grep -lz 'this[[:space:]]*is[[:space:]]*some[[:space:]]*text' {} +
空白は単語の間にのみ入れられることを考慮してください。
現在のディレクトリからすべてのファイルを再帰的に検索したいだけなら、 は不要で、 (recursive)find
だけを使用できます。を使用して、検索するファイルを選択することができます (たとえば、除外するディレクトリのファイルを選択するなど)。 つまり、単純に次のようになります。grep -r
find
grep -rlz 'this[[:space:]]*is[[:space:]]*some[[:space:]]*text' .
ここでの主なトリックは
-z
、入力ストリームの各行を改行ではなく ASCII NUL で終了するように処理することです。その結果、通常の方法を使用して改行を一致させることができます。[[:space:]]
文字クラス パターンは、スペース、タブ、CR、LF などの空白文字を示します。したがって、これを使用して、単語間に含まれる可能性のあるすべての空白文字を一致させることができます。grep -l
は、希望するパターンのいずれかを含むファイル名のみを出力します。一致したものも出力したい場合は、-H
の代わりにを使用します-l
。
一方、空白が単語以外の任意の場所に来る可能性がある場合、見た目が悪くなります。
grep -rlz
't[[:space:]]*h[[:space:]]*i[[:space:]]*s[[:space:]]*i[[:space:]]*\
s[[:space:]]*s[[:space:]]*o[[:space:]]*m[[:space:]]*e[[:space:]]*\
t[[:space:]]*e[[:space:]]*x[[:space:]]*t' .
-P
(PCRE) オプションを使用すると、 を[[:space:]]
次のように置き換えることができます\s
(見た目がずっと良くなります):
grep -rlzP 't\s*h\s*i\s*s\s*i\s*s\s*s\s*o\s*m\s*e\s*\
t\s*e\s*x\s*t' .
@steeldriver の提案を使用してsed
パターンを生成するのが最善の選択肢です。
grep -rlzP "$(sed 's/./\\s*&/2g' <<< "thisissometext")" .
答え2
すべての空白を削除して grep することができます:
tr -d '[[:space:]]' < foo | grep thisissometext
延長中:
find . -type f -exec bash -c 'for i; do tr -d "[[:space:]]" < "$i" | grep -q thisissometext && printf "%s\n" "$i"; done' _ {} +
コマンドbash
を展開すると次のようになります。
for i
do
tr -d "[[:space:]]" < "$i" |
grep -q thisissometext &&
printf "%s\n" "$i"
done
これはすべての引数をループし、上記のテストを使用します。
答え3
以下のコードは、ディレクトリを再帰的にファイルを検索し、" "
とのすべての出現を削除します"\n"
。文字列が残りのテキストに存在する場合、一致があります。これは、スペース/改行がどれでもファイル内の文字列内の位置。
何をするのか
一致するファイルが見つかった場合、次のようにパスを含めてターミナルに表示されます。
/home/jacob/Bureaublad/testmap/test2.txt
/home/jacob/Bureaublad/testmap/Naamloze map 2/test1.txt
読み取り不可能なファイルに遭遇した場合にスクリプトが中断するのを防ぐために組み込んだ try / except。
スクリプト
#!/usr/bin/env python3
import os
import sys
s = sys.argv[2]
for root, dirs, files in os.walk(sys.argv[1]):
for file in files:
file = root+"/"+file
try:
if s in open(file).read().replace(" ", "").replace("\n",""):
print(file)
except:
pass
使い方
- スクリプトを空のファイルにコピーし、
find_string.py
ディレクトリと文字列を引数として実行します。
python3 /path/to/find_string.py <directory> <string_to_find>
文字列またはディレクトリにスペースが含まれている場合は、引用符を使用します。
python3 /path/to/find_string.py '<directory>' '<string_to_find>'
注記
このスクリプトは、空白または改行のいずれかを含む文字列を含むファイルを検索します。行内の他の文字/文字列 (タブなど) で拡張できます。
if s in open(file).read().replace(" ", "").replace("\n",""):
答え4
改行文字を扱うためにgrep -i --recursive 'word1\|word2' *
、およびを使うことができます。awk '/word1/,/word2/'