パイプからディレクトリにすべてのファイルを移動するには?

パイプからディレクトリにすべてのファイルを移動するには?

デスクトップディレクトリのすべての要素に対してfileコマンドを実行しました。

~/Desktop > file * 

次に、説明に文字列 "image"を含むすべての行を検索します。

~/Desktop > file * | grep "image"

次に、各行からファイル名を削除します。

~/Desktop> file * | grep "image" | cut -d: -f1

このステップでは、取得したすべてのファイル名をディレクトリに移動する方法がわかりません。 xargsを試しましたが、間違って理解したようです。

~/Desktop> file * | grep "image" | cut -d: -f1 | xargs mv {} ./dirk

答え1

--target-directoryオプションmvを見る

答え2

{}xargs廃止された-iオプションを渡したり-I {}、 。

file * | grep "image" | cut -d: -f1 | xargs -I {} mv {} ./dirk

これは、ファイル名に特殊文字(:\"'または改行、イニシャル-、スペースが使用されているxargs -I)が含まれていない場合にのみ機能します。これにはimages画像でなくてもファイル名も含まれます。これには、file図のイメージだけでなく、「ディスクイメージ」などのコマンドが「イメージ」として記述するファイルも含まれます。

コンテンツが画像であるファイルをフィルタリングするより安定しているが完璧ではない方法は、で説明されているfile -iファイルを使用して検索することです。以下のコードは、一部のバージョンの¹を混同する可能性がある引用符文字も変換します。FILENAME: image/TYPExargs

file -i ./* |
sed -n -e 's/["'\''\\]/\\&/' -e 's/: *image\/[^:]*$//p' |
xargs -I {} mv {} ./dirk

最新バージョンのGNUユーティリティ(つまり、組み込まれていないLinuxシステムまたはCygwin)では、空白で区切られたリストを使用して処理を安定して少し速くすることができます。

file -0i ./* |
sed -z -e 's/: *image\/[^:]*$//p' |
xargs -0 mv -t ./dirk

別の方法はループを使用するか、ファイルを繰り返すことです。file *これは、コマンドラインの長さの制限のために失敗しても機能します。find

for x in ./*; do
  if [ -n "$(file -i "$x" | sed -n '$/: *image\/[^:]*$/ p')" ]; then
    mv "$x" ./dirk
  fi
done

1 POSIXは引用符の処理が無効になっていることを意味しますが、4.4.2現在のfindutilsのGNUバージョンではそうではありません。-Ixargs

関連情報