/home/user/temps
487個のフォルダーがあるという名前のフォルダーがあります。各フォルダーには、thumb.pngというファイルがあります。
thumb.pngという名前のすべてのファイルを別のフォルダーにコピーし、元のフォルダーに基づいて名前を変更します。
/home/user/temps
487個のフォルダーがあるという名前のフォルダーがあります。各フォルダーには、thumb.pngというファイルがあります。
thumb.pngという名前のすべてのファイルを別のフォルダーにコピーし、元のフォルダーに基づいて名前を変更します。
回答:
どうぞ:
for file in /home/user/temps/*/thumb.png; do new_file=${file/temps/new_folder}; cp "$file" "${new_file/\/thumb/}"; done;
編集:
ところで、標準的な知恵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
行内の引用符は、ファイル名のスペースや改行などを処理するために重要です。
new_file/\/thumb
ですか?
${VARIABLE/PATTTERN/REPLACEMENT}
の値を生成しますVARIABLE
が、パターンは置換テキストに置き換えられます。ここで、パターンは/thumb
(の/
よう${new_file//PATTERN/REPLACEMENT}
に見えないようにエスケープする必要があるため、最初に出現する置換の代わりにグローバル置換になります)、置換テキストは空です。
これは、任意の深さのサブディレクトリに対して機能します。
$ 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の親ディレクトリからコマンドを実行しました。置換cp
しecho
て実験します。
これを試して
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
編集
ディレクトリ名に空白文字が埋め込まれている場合の引用を追加しました。
また、実行するコマンドのみを出力するように変更しました。スクリプトの出力を調べて、すべてのファイル/パス名が適切に見えることを確認します。実行されるコマンドに問題がないことを確認したら、を削除しecho
ます。
mv -i ./A A/thumb.png ../tmp/.png
します。
find -type d
、出力を見ることができます。それはあなたが期待するすべてのディレクトリを取得しますか?そうでない場合は、問題を示すために出力を追加してください。幸運を。
read dir
ワード分割を実行し、ディレクトリa\nb
aとbから2つのインスタンスを取得しますが、マスキングでは解決できません。
コピーするには、コマンドcpが必要です。また、linuxの名前を変更することは、ファイルを移動することと同じなので、mvコマンドで実行する必要があります。Linuxでは、もちろん、ソースから別のフォルダーにある場合はもちろん、宛先フォルダーへのパス全体を指定する必要があります。私はコピーのために、このようなものになるだろう:
cp /source_path/file /destination_path/
または名前を変更または移動する
mv /source_path/old_file /destination_path/new_name_file