ファイルシステムに散在する同じ名前のすべてのファイルを1つのフォルダに移動するには?

ファイルシステムに散在する同じ名前のすべてのファイルを1つのフォルダに移動するには?

別の場所に同じ名前のファイルを持つファイルシステムツリーがあります。コマンドラインで次のコマンドを試しました。

find / -name "HAHA" -exec mv {} /home \;

1つのファイルでのみ機能し、別のファイルの場合は同じ名前のエラーメッセージが表示されます。

各ファイル名に数字を追加して区別するようにコマンドを変更できますか?

ここに画像の説明を入力してください。

答え1

2つの考えられる解決策を考えることができます。

  1. 出身mvならGNUコアツール(そうである可能性があります)次に、次のコマンドを実行します。

    find / -name "HAHA" -type f -exec mv --backup=numbered "{}" /home \;
    

    ...呼び出したすべてのファイルを.thisHAHAに移動します。/home--backup=numbered オプションofは、コマンドが実行されるmvたびに、mv指定されたファイルがターゲットディレクトリにすでに存在することを確認しますHAHA。その場合は、新しいファイルをに移動する前に、最初に名前をHAHA.~n~(増えた数字)に変更します。最後に、そのような名前のファイルを取得します。n/homeHAHAHAHA.~1~HAHA.~2~/home

  2. このシェルスクリプトはトリックを実行する必要がありますが、改行文字を含むパスに抵抗しません。

    IFS="
    "      # if you are using bash, you can just use IFS=$'\n' here
    i=1
    for file in $(find / -name "HAHA" -type f); do
      mv "${file}" "/home/HAHA${i}"
      i=$((${i} + 1))
    done
    

    HAHAこれはすべてのファイルを繰り返し、各ファイルをに移動します/home/HAHAn。ここでn数字は再び1から増加し始めます。

答え2

小さなスクリプトで簡単な解決策を見つけました。スクリプトはcpf(またはユーザーが指定した名前で)呼び出され、次のようになります。

#!/bin/bash

dir=xyz       # Directory where you want the files
num=1

for file in "$@"
do
    base=`basename -- "$file"`
    mv -- "$file" "$dir/$base.$num"
    num=$(($num+1))
done

次のようにコマンドを実行します。

find . -name HAHA -print0 | xargs -0x cpf

答え3

whileループを使用します。

i=1
find / -name 'HAHA' -print0 | while read -d '' -r file; do mv "$file" "/home/${file##.*/}$((i++))"; done

ここで重要なのは、print0オプションが(optionsfindと共に)名前にスペースを含むファイルを正しく処理することです。このような操作を一度だけ行う必要がある場合は、最初の行を設定する必要はありません。 (他のほとんどのシェルと同様に)この変数は自動的に生成されるためです。-d ''readi=1bash

答え4

GNU 並列性を使用できます。

find / -name "HAHA" -type f | parallel 'echo mv {}
 ./dest-dir/{/}_`stat -c%i {}`

{/}  ............. returns dirname
{/.} ............. dirname with no extension
stat -c%i {} ..... gets the inode for each file "whic is unique"

OBS:echoテストに使用し、必要に応じて削除します。

関連情報