私が指定したファイルに関する情報を返す「file」の結果を使用しようとしています。
例えば
file *.doc 'all .doc extensions
次に、「生成アプリケーション名:Microsoft Word」を含むファイルに関する情報を返します。それでは、「Word」という文字列の結果を検索してみましょう。私はここに閉じ込められています。実際にどうすればいいですか?
*数時間の検索の最後に試してみた内容です。私が探している単語が何であるかわかりません。アドバイスしてください。
find . -type f -print0 | xargs -0 grep -lh "Microsoft Word" | xargs -I % mv % ../NewDirectory/
私はこれがファイル自体から「Word」という文字列を検索して新しいディレクトリに移動すると思いました。
答え1
私が正しく理解したら、ファイルを現在のディレクトリとそのサブディレクトリから別のディレクトリに再帰的に移動したいのですが、コマンドがそのファイルをfile
「Microsoft Word」ファイルとして報告する場合にのみ可能です。つまり、file "$filename" | grep 'Microsoft Word'
いくつかの出力を生成するファイルに興味があります。
簡単な方法は、落ち着いて仕事を一つずつ処理することです。現在のディレクトリのファイルのみが必要な場合は、for
ループとワイルドカードパターンを使用できます。
for f in *.doc; do
if …
done
条件は何ですか?出力Microsoft Word
にfile "$f"
。私file --
はで終わる名前を避けた-
。
for f in *.doc; do
if file -- "$f" | grep -s 'Microsoft Word'; then
…
fi
done
私たちがしなければならないのは、ファイルを移動するコマンドを追加することだけです。
for f in *.doc; do
if file -- "$f" | grep -s 'Microsoft Word'; then
mv -- "$f" ../NewDirectory/
fi
done
サブディレクトリでもファイルを見つけるには、次のようにします。**
ワイルドカードパターン再帰的なワイルドカードに使用されます。 Bashで有効にするには、を使用する必要がありますshopt -s globstar
(ksh93ではを実行しset -o globstar
、zshではすぐに機能します。他のシェルにはこの機能はありません)。 bash 4.2以下では、ディレクトリへのシンボリックリンクに従います。
for f in **/*.doc; do
if file -- "$f" | grep -s 'Microsoft Word'; then
mv -- "$f" ../NewDirectory/
fi
done
移動されたすべてのファイルは../NewDirectory/
生成されたサブディレクトリなしで終了することに注意してください。ディレクトリツリーを再現するには、次のものを使用できます。文字列操作構造ファイル名のディレクトリ部分を抽出し、mkdir -p
必要に応じてターゲットディレクトリを作成します。
for f in ./**/*.doc; do
if file "$f" | grep -s 'Microsoft Word'; then
d="${f%/*}"
mkdir -p ../NewDirectory/"$d"
mv "$f" ../NewDirectory/"$d"
fi
done
file
やや脆弱な出力を解析するよりも、出力を標準化された文字列に解析する方が良いかもしれません。file -i
答え2
最初の例は一重引用符が一致しないため動作しませんが、file
2番目の例のためにその点を見つけたようです。
これにより:
find . -type f
出力を見ることができます。ファイル名です。その出力から何かを選択するには、grep
次のようにします。
find . -type f | grep "Microsoft Word"
リストされたファイルの内容ではなく、ファイル名で検索してください。ファイル名に改行文字を含めることができ、「Microsoft Word」を含むファイル名に名前の一部として改行文字を含めると、出力が不完全であるため、これは完全に正確ではありません。
これにより:
find . -type f -print0 | xargs -0 grep -lh "Microsoft Word"
このxargs
部分は実際にはファイル名をgrepに渡します(-print0
forfind
と-0
forはxargs
改行文字を含むファイル名を処理します)。これにより、「Word」だけでなく「Microsoft Word」の完全な文字列も検索されます。ファイルに。
指定された-lh
forはgrep
ファイル名をリストし、ファイル名の改行が正常に印刷されるため問題がある可能性があるため、-Zを指定してNULで終わるファイル名を引き続き使用する必要があります。指定しないと-l
行一致も実行されるため、追加処理がmv
できなくなります。
すべてのファイルを1つのディレクトリに移動したい場合は、通常、オプション(代わりに入力から読み取った引数をデフォルトの行の末尾とは別の場所に置くことができますが遅い)を使用する方がmv -t
簡単です。 mvはファイルごとに1回呼び出されます。)xargs
-I
xargs
find . -type f -print0 | xargs -0 grep -lhZ "Microsoft Word" | xargs -0 mv -t ../NewDirectory/
これにより、すべてのファイルが「Microsoft Word」を含む現在のディレクトリの下の場所に移動されます。コンテンツNewDirectory
現在のディレクトリの横に 。必ず存在しなければならないことに注意してください../NewDirectory
。