/home/user/temps
487 klasör içeren bir klasör var . Her klasörde thumb.png adlı bir dosyam var.
Thumb.png adlı tüm dosyaları ayrı bir klasöre kopyalamak ve geldikleri klasöre göre yeniden adlandırmak istiyorum.
/home/user/temps
487 klasör içeren bir klasör var . Her klasörde thumb.png adlı bir dosyam var.
Thumb.png adlı tüm dosyaları ayrı bir klasöre kopyalamak ve geldikleri klasöre göre yeniden adlandırmak istiyorum.
Yanıtlar:
Hadi bakalım:
for file in /home/user/temps/*/thumb.png; do new_file=${file/temps/new_folder}; cp "$file" "${new_file/\/thumb/}"; done;
Düzenle:
kanonik bilgelik, bu arada, bunun find
için kötü bir fikir olduğudur - sadece kabuk genişletmeyi kullanmak çok daha güvenilirdir. Ayrıca, bu varsayılır bash
, ancak bunun güvenli bir varsayım olduğunu anlıyorum :)
düzenleme 2:
açıklık için, onu yıkacağım:
# 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}
yapı ile ilgili detaylar burada bulunabilir .
cp
satırdaki alıntılar dosya adlarındaki boşlukları ve satırsonlarını vb. işlemek için önemlidir.
new_file/\/thumb
?
${VARIABLE/PATTTERN/REPLACEMENT}
üretir VARIABLE
ancak kalıp yerine yedek metnin yerini alır. Burada desen /thumb
(ilk /
görünme ${new_file//PATTERN/REPLACEMENT}
yerine global bir değiştirme yapan, görünmemesi için kaçması gerekir ) ve değiştirme metni boştur.
/home/user/temps
, ki bu sorudan net değil. Eğer böyle değilse, sen gerek bulmak ya **
.
Bu, keyfi olarak derin alt dizinler için çalışır:
$ 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'
Aradaki kısım parametre genişletmedir ${NAME//\//_}
. Bu içeriği alır NAME
ve her oluşumunu değiştirir /
ile _
.
Not: sonuç, çalışma dizinine ve find için path parametresine bağlıdır. Komutu temps'in üst dizininden yürüttüm. Denemek için cp
ile değiştirin echo
.
Kısa yardımcı kodu:
#!/bin/bash
#
# echo cp "$1" ../tmp/"${1//\//_}"
#
mv "$1" ../tmp/"${1//\//_}"
hadi 'deslash.sh' adını verelim ve çalıştırılabilir yapalım. Şununla ara:
find -type f -name thumb.png -exec ./deslash.sh {} ";"
Bir çarpışma olursa başarısız olur
a/b/thumb.png # and
a_b/thumb.png
ama bu kaçınılmaz.
Bunu dene
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
Düzenle
Ben dir isimlerinden herhangi birinde beyaz boşluk karakterleri gömülü olması durumunda alıntı ekledim.
Ayrıca bunu değiştirdim, böylece sadece çalıştırılacak komutları yazdıracağım. Tüm dosyaların / yol adlarının düzgün göründüğünden emin olmak için komut dosyasının çıktısını inceleyin. Yürütülecek komutlarla ilgili herhangi bir sorun olmadığından emin olduğunuzda echo
,.
mv -i ./A A/thumb.png ../tmp/.png
- tüm dosyalar ../tmp/.png ile biter (../tmp hedef hedefimdir).
find -type d
çıktısını görebilirsiniz. Bu beklediğiniz tüm dizinleri alıyor mu? Değilse, sorunu göstermek için lütfen bir miktar çıktı ekleyin. İyi şanslar.
read dir
kelime bölme işlemini gerçekleştirir ve a\nb
a ve b dizininden hiçbir maskelemenin çözemediği iki örnek olarak alır .
Kopyalamak için cp komutuna ihtiyacınız vardır ve linux için yeniden adlandırmak dosyayı taşımaktan farklıdır , bu yüzden mv komutuyla yapmanız gerekir . Linux'ta her zaman, başka bir klasördeyseniz ve hedef klasöre kaynaktan tüm yolu belirtmeniz gerekir. Kopya için şöyle bir şey olurdum:
cp /source_path/file /destination_path/
veya yeniden adlandırmak veya taşımak için
mv /source_path/old_file /destination_path/new_name_file