別の場所に同じ名前のファイルを持つファイルシステムツリーがあります。コマンドラインで次のコマンドを試しました。
find / -name "HAHA" -exec mv {} /home \;
1つのファイルでのみ機能し、別のファイルの場合は同じ名前のエラーメッセージが表示されます。
各ファイル名に数字を追加して区別するようにコマンドを変更できますか?
答え1
2つの考えられる解決策を考えることができます。
出身
mv
ならGNUコアツール(そうである可能性があります)次に、次のコマンドを実行します。find / -name "HAHA" -type f -exec mv --backup=numbered "{}" /home \;
...呼び出したすべてのファイルを.this
HAHA
に移動します。/home
--backup=numbered
オプションofは、コマンドが実行されるmv
たびに、mv
指定されたファイルがターゲットディレクトリにすでに存在することを確認しますHAHA
。その場合は、新しいファイルをに移動する前に、最初に名前をHAHA.~n~
(増えた数字)に変更します。最後に、そのような名前のファイルを取得します。n
/home
HAHA
HAHA.~1~
HAHA.~2~
/home
このシェルスクリプトはトリックを実行する必要がありますが、改行文字を含むパスに抵抗しません。
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 ''
read
i=1
bash
答え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
テストに使用し、必要に応じて削除します。