ディレクトリにこのようなファイルがあります
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
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つのタスク{}
ファイル名{.}
拡張子のないファイル名
三。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