
現在のディレクトリにあるすべてのファイルのMIMEタイプを取得したいと思います。なぜこれがうまくいかないのですか? OSXまたはLinuxでbashをテストしました。 「ファイル」はファイルが見つからないと文句を言いますが、まったく同じパスを使用して実行すると機能します。
$ find . -type f | xargs -n 1 -I FILE echo $(file --mime-type -b FILE)
ERROR: cannot open './foo.txt' (No such file or directory)
...
$ file --mime-type -b ./foo.txt
text/plain
もちろん、実際の世界では、応答を「エコー」するのではなく、他のコマンドでMIMEタイプの文字列を使用する必要があります。
これが私が解決できる最も簡単な問題です。ファイル名の置き換えについて何かを理解していないと思いますかxargs
?
答え1
コマンドの置き換え$(file --mime-type -b FILE)
は に渡される前にシェルによって実行されるため、xargs
必要なものは表示されません。 xargsを介して引用して$(file --mime-type -b FILE)
渡します。bash -c
find . -type f | xargs -n 1 -I FILE bash -c 'echo $(file --mime-type -b FILE)'
答え2
ここでは悪用する必要はありませんxargs
。find
スイッチを使用してください-exec
。
$ find . -type f -exec file --mime-type -- {} +
はい
基本file
出力
$ find 8* -type f -exec file --mime-type -- {} + | tail -5
89999/sample10.txt: text/plain
89999/sample2.txt: text/plain
89999/sample4.txt: text/plain
89999/sample6.txt: text/plain
89999/sample9.txt: text/plain
file -b
出力
$ find 8* -type f -exec file --mime-type -b -- {} + | head -5
application/x-empty
text/x-perl
text/plain
text/plain
text/plain
代替
mimetype
これは参考用ですが、同じ操作を実行するために使用できる別のコマンドがありますfile --mimetype
。このコマンドはFedoraのこのパッケージの一部であり、同様にperl-File-MimeInfo
機能します。
$ find 8* -type f -exec mimetype -- {} + | tail -5
89999/sample10.txt: text/plain
89999/sample2.txt: text/plain
89999/sample4.txt: text/plain
89999/sample6.txt: text/plain
89999/sample9.txt: text/plain
より詳細な実装
「単にecho..以上」について質問し、..を使用しようとしていることを考えると、..をxargs
使用する必要があると思うという結論を下しますxargs
。
ただし、を使用している場合、find
これは通常最善のアプローチではありません。より複雑な方法でこれを行うのではなく、スイッチでfind
シェルを使用して呼び出すことで、より複雑な操作を実行できます。find
-exec
xargs
$ find . -type f -exec sh -c '
cmd1;
cmd2;
file --mime-type -b "$@";
cmd3;
cmd4;
' sh {} \;
メモ:+
複数のパラメータを渡すターミネータを使用することから、file --mime-type ...
一度に1つのパラメータを渡すことに切り替えました\;
。
はい
$ find 8* -type f -exec sh -c '
echo -n "mime-type: ";
file --mime-type -b "$@"
' sh {} \; |& tail -10
mime-type: text/plain
mime-type: text/plain
mime-type: text/plain
mime-type: text/plain
mime-type: text/x-shellscript
mime-type: text/plain
mime-type: text/plain
mime-type: text/plain
mime-type: text/plain
mime-type: text/plain
答え3
あなたの問題はシェル拡張に関連しています。 $() は引数として渡される前に拡張されます。現状のまま処理するには、一重引用符で囲み、シェルを呼び出します。
また、ファイル名を扱う場合は、print0と0を使用する習慣を持ちます。これを省略すると、空白文字を含むファイル名に問題が発生する可能性があります。
例:
find . -type f -print0 | xargs -0 -n 1 -I FILE bash -c 'echo $(file --mime-type -b FILE)'
あなたの場合、これは次のように単純化することができます。
find . -type f -print0 | xargs -0 -n 1 file --mime-type -b
追加の説明:見つかったすべてのファイル( "xargs -n 1"またはfind + exec)に対してプログラムを呼び出すと、実際のパフォーマンスのボトルネックが発生する可能性があります。ディレクトリに何千ものファイルが含まれている場合、何千ものプロセスが作成されます。