1つのディレクトリにそのようなファイルがいくつかあります
00.01.02 0000 some filename 1.pdf
00.01.02 0000 some filename 1.txt
02.03.07 0163 another filename 2.pdf
02.03.07 0163 another filename 2.txt
特定の文字列を含むすべての txt ファイルを見つけて、この txt ファイルと対応する pdf ファイルを別のディレクトリに移動する必要があります。
これを実行する最善の方法は何ですか?
答え1
3 つのオプションがあります。基本的な考え方は次のとおりです。
grep | xargs mv
grep | parallel mv
find -exec grep -q -exec mv
1.grep | xargs mv
使用しgrep
てxargs
:
grep -FlZ "some string" *.txt \
| xargs -0 -I{} sh -c 'echo mv "$1" "${1%.*}.pdf" some/other/directory' xargs-sh {}
grep
:
-F
パターンではなく文字列全体に一致します-l
一致するファイル名のみ出力-Z
ファイル名の間にゼロ区切り文字を出力します (ファイル名には改行文字が許可されているため、区切り文字として改行文字を使用することはできないため、これは重要です)
xargs
:
-0
ゼロ区切りのデータを読み取ります
2.grep | parallel mv
対応する PDF ファイル名を取得するには、xargs
を使用してサブシェルを呼び出す必要があります。sh -c
そうする代わりに、GNU parallel
クールな機能を活用することもできます!!
grep -FlZ "some string" *.txt \
| parallel -0 -j1 echo mv {} {.}.pdf some/other/directory
-j1
一度に1つの仕事だけ{}
ファイル名{.}
拡張子なしのファイル名
3.find -exec grep -q -exec mv
もう一つの代替案として、以下を使用しますfind
。
find . -maxdepth 1 -name "*.txt" \
-exec grep -Fq "some string" {} \; \
-exec sh -c 'echo mv "$1" "${1%.*}.pdf" some/other/location' find-sh {} \;
-maxdepth 1
再帰しないgrep -q
ファイル名ではなくエラー コードのみを取得する場合、2 番目は-exec
最初のものが成功した場合にのみ実行されます。- 2 番目は基本的に最初のオプション
-exec
と同じです。xargs
- ファイル名を渡さないので、ゼロ区切りの出力を行う必要はありません
find
。
各オプションについて、echo
出力に満足している場合は を削除します。
答え2
問題を細分化します。
「現在のディレクトリ内で、特定の文字列を含むすべてのテキスト ファイルを見つける必要があります」。
grep -F "text string just as written (no regex)" *.txt
「私はファイル名これらのファイルの
grep -l -F "text string" *.txt
「これらのファイルごとに...」
for...each はwhile/do/done
、ファイルリストを渡す構文を使用して実行します。各ファイルに対して、以下を実行できます。何か変数にアクセスできるようになります$file
:
grep -l -F "text string" *.txt \
| while IFS= read -r file ; do
...something...
done
「何か」とは
「...txt ファイルと対応する pdf ファイルを移動します...」
したがって、「.txt」を除いたベース名が必要です。
BASE=$( basename ${file} .txt )
最後にすべてをまとめると次のようになります。
grep -l -F "text string" *.txt \
| while IFS= read -r file ; do \
BASE=$( basename ${file} .txt )
mv ${BASE}.txt /some/other/dir
mv ${BASE}.pdf /some/other/dir
done
(注意:これは、各ファイルパスがないため、basename
パスが削除されてしまいます。
答え3
parallel
コマンドがない場合は、xargs
以下の2つを実行します
grep -l 'search string' *.txt | xargs -I {} basename {} .txt | xargs -I {} cp {}.pdf /destination-directory