web-dev-qa-db-ja.com

Linuxの「検索」機能で見つかったファイルをコピーして名前を変更するにはどうすればよいですか?

/home/user/tempsという名前のフォルダに487個のフォルダがあります。各フォルダには、thumb.pngというファイルがあります。

Thumb.pngという名前のすべてのファイルを別のフォルダーにコピーし、元のフォルダーに基づいて名前を変更したいと思います。

17
Mirage

どうぞ:

for file in /home/user/temps/*/thumb.png; do new_file=${file/temps/new_folder}; cp "$file" "${new_file/\/thumb/}"; done;

edit:

ちなみに、正規の知恵は、これにfindを使用するのは悪い考えです。単にシェル展開を使用する方がはるかに信頼性が高いということです。また、これはbashを想定していますが、これは安全な想定だと思います:)

編集2:

明確にするために、私はそれを分解します:

# Shell-expansion to loop specified files
for file in /home/user/temps/*/thumb.png; do

    # replace 'temps' with 'new_folder' in the path
    # '/home/temps/abc/thumb.png' becomes '/home/new_folder/abc/thumb.png'
    new_file=${file/temps/new_folder};

    # drop '/thumb' from the path
    # '/home/new_folder/abc/thumb.png' becomes '/home/new_folder/abc.png'
    cp "$file" "${new_file/\/thumb/}";
done;

${var/Pattern/Replacement}構成の詳細については、 ここ を参照してください。

cp行の引用符は、ファイル名のスペースや改行などを処理するために重要です。

8
simon

これは任意の深いサブディレクトリで機能します。

$ find temps/ -name "thumb.png" | while IFS= read -r NAME; do cp -v "$NAME" "separate/${NAME//\//_}"; done
`temps/thumb.png' -> `separate/temps_thumb.png'
`temps/dir3/thumb.png' -> `separate/temps_dir3_thumb.png'
`temps/dir3/dir31/thumb.png' -> `separate/temps_dir3_dir31_thumb.png'
`temps/dir3/dir32/thumb.png' -> `separate/temps_dir3_dir32_thumb.png'
`temps/dir1/thumb.png' -> `separate/temps_dir1_thumb.png'
`temps/dir2/thumb.png' -> `separate/temps_dir2_thumb.png'
`temps/dir2/dir21/thumb.png' -> `separate/temps_dir2_dir21_thumb.png'

興味深い部分は パラメータ展開${NAME//\//_}です。 NAMEの内容を取得し、/が出現するたびに_に置き換えます。

注:結果は、作業ディレクトリと検索のパスパラメータによって異なります。 tempsの親ディレクトリからコマンドを実行しました。実験するには、cpechoに置き換えます。

5
lesmana

短いヘルパーコード:

#!/bin/bash
#
# echo cp "$1" ../tmp/"${1//\//_}" 
#
mv "$1" ../tmp/"${1//\//_}"

'deslash.sh'という名前を付けて、実行可能にします。それを呼び出す:

find -type f -name thumb.png -exec ./deslash.sh {} ";"    

衝突が存在する場合、失敗します

a/b/thumb.png # and 
a_b/thumb.png 

しかし、それは避けられません。

1
user unknown

これを試して

mkdir /home/user/thumbs
targDir=/home/user/thumbs

cd /home/user/temps

find . -type d | 
 while IFS="" read -r dir ; do
   if [[ -f "${dir}"/thumb.png ]] ; then
     echo mv -i "${dir}/thumb.png" "${targDir}/${dir}_thumb.png"
   fi
done

編集

ディレクトリ名に空白文字が埋め込まれている場合に備えて、引用符を追加しました。

また、これを変更してonly実行するコマンドを出力します。スクリプトの出力を調べて、すべてのファイル/パス名が適切に見えることを確認します。実行されるコマンドに問題がないことを確認したら、echoを削除します。

0
shellter