web-dev-qa-db-ja.com

ファイル名の最初の単語に基づいてファイルを移動するにはどうすればよいですか?

フォルダには、次のような数千のファイルがあります。

cat eats mouse.jpg
cat chases mouse.jpg
gorilla eats banana.jpg
gorilla is sleeping.jpg
elephant is huge.jpg
elephant has trunk.jpg
(and so on...)

私は、ファイル名の最初のWordに基づいてこれらのファイル(猫、ゴリラ、象など)を、最初のWordに基づいて作成されたフォルダーに移動するbashスクリプトが必要です。

  • 「cat」フォルダーが作成され、「cat」で始まるすべてのファイルがこのフォルダーに移動されます。
  • 「gorilla」フォルダが作成され、「gorilla」で始まるすべてのファイルがこのフォルダに移動さ​​れます。
  • 「elephant」フォルダが作成され、象で始まるすべてのファイルがこのフォルダに移動さ​​れます。
  • (等々..)
1
user163125

次のワンライナーは仕事をするべきです:

_find . -maxdepth 1 -type f -name '*.jpg' -exec Perl -e '$a="{}"; $a =~ /(\w+)/; `mkdir -p $1 && mv "$a" $1`' \;
_

説明

  • _find . -maxdepth 1 -type f -name '*.jpg'_は、現在のフォルダー(_-type f_)で拡張子jpgのファイル(_. -maxdepth 1_)のみを検索します。

  • _-exec_は、一致するすべてのファイルに対してPerlコマンドを呼び出します。文字列_{}_は、処理中の現在のファイル名に置き換えられます。

  • _$a="{}";_は現在のファイルを保存します

  • $a =~ /(\w+)/は正規表現テストです。特殊変数_$1_には、_$a_に保存されているファイル名の最初のワードが含まれます。

  • 最後に、_mkdir -p $1 && mv "$a" $1_は、_/bin/sh_またはそれと同等のシステムコマンドとして実行されます。 mkdirの_-p_オプションに注意してください。ディレクトリがすでに存在する場合でも失敗しません。

enter image description here


更新

Perlでのコードインジェクションを防ぐには(@ geirha に感謝)、次のように quotemeta 関数を使用します。

_find . -maxdepth 1 -type f -name '*.jpg' -exec Perl -e '$a="\Q@ARGV"; $a =~ /(\w+)/; `mkdir -p $1 && mv $a $1`' "{}" \;
_
7
Sylvain Pineau

これにはforループを使用します。

for file in ./*" "*.jpg; do
    Word=${file%% *}
    mkdir -p "$Word" &&
    mv "$file" "$Word"
done

これを対話型シェルで実行するか、スクリプトに追加できます。 Bashは知っておくと非常に役立つので、時間があるときに Bash Guide を読んで学習することをお勧めします。

3
geirha