mv: olamaz stat Kabuk betiğinde böyle bir dosya veya dizin yok


16

Bazı dosyaları bir klasörden başka bir klasöre taşımak için bir komut dosyası yazdım ama aşağıdaki hatayı aldım, 2 klasörü kontrol ettim ve 1 klasör için bu tür dosyalar olduğunu fark ettim ve başka bir dosya yok, ama neden hepsi "mv gösteriyor stat böyle bir dosya veya dizin yok "

    mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/194.199.68.165_tcp.folder/data/*': No such file or directory
    mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/194.42.17.124_tcp.folder/data/*': No such file or directory
    mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/195.113.161.13_tcp.folder/data/*': No such file or directory
    mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/203.159.127.3_tcp.folder/data/*': No such file or directory
    mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/212.199.61.205_tcp.folder/data/*': No such file or directory
    mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/212.51.218.235_tcp.folder/data/*': No such file or directory
    mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/213.73.40.105_tcp.folder/data/*': No such file or directory
    mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/41.225.7.4_tcp.folder/data/*': No such file or directory
    mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/83.230.127.122_tcp.folder/data/*': No such file or directory
    [esolve@kitty tcp_50x50]$ ls /home/wgong/project/capture/tcp_50x50/dest_folder/194.199.68.165_tcp.folder/
    [esolve@kitty tcp_50x50]$ ls /home/wgong/project/capture/tcp_50x50/dest_folder/203.159.127.3_tcp.folder/data/
    129.88.70.226   132.187.230.1    138.96.116.22   155.185.54.250   192.38.109.144  193.136.227.163  193.175.135.61  195.113.161.13  83.230.127.122
    130.104.72.200  132.227.62.122   147.83.29.232   156.17.10.52     192.42.43.22    193.137.173.218  193.205.215.74  212.199.61.205
    131.130.69.164  132.252.152.194  148.81.140.193  157.181.175.249  192.43.193.71   193.144.21.131   193.226.19.30   212.51.218.235
    131.188.44.102  134.151.255.180  152.66.245.162  160.78.253.31    193.1.170.136   193.145.46.243   194.199.68.165  213.73.40.105
    131.254.208.10  138.48.3.203     152.81.47.4     192.114.4.3      193.136.166.56  193.166.160.98   194.42.17.124   41.225.7.4

komut dosyası:

    list=`ls dest_folder`
    cd dest_folder
    cwd=`pwd`
    for folder in $list;do
            mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
    done

Koştum /home/esolve/project/capture/tcp_50x50/


1
Lütfen betiğin ilgili bölümlerini gösterin.
Mat

Sorumu güncelledim ve senaryoyu ekledim, teşekkürler!
misteryes

Eğer bir eklemem gerekir mi -rhiç mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}?
ProfessionalAmateur

-riçin bir seçenek yokmv
misteryes

Yanıtlar:


25
mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}

Buradaki tırnak işaretleri ( ') kabuğun globbing yapmasını engeller. *İçin tam anlamıyla geçirilmediğini mvdenir dosyaları bulmak olmadığından başarısız komutu, *belirtilen dizinlerde.

Bunu şu şekilde değiştirin:

mv "${cwd}/${folder}/data"/* "${cwd}/${folder}"

(İçinde boşluklar olan bir dizin adınız varsa, sorunları önlemek için çift tırnak. *Tırnak işareti dışında.)

Yine de boş dizinlerin hatalarını alacaksınız. (Aynı tür bir neden: dosya kalıp için bir eşleşme bulamazsa, kalıbın kendisini bir argüman olarak komuta iletir.)


Çift tırnak işaretleri mantıklı, ancak neden *tırnak işaretleri dışına koymam gerekiyor ?
Sibbs Kumar

Genişletmek istiyorsanız, @SibbsGambling
Mat

8

Kodunuzla ilgili birkaç sorun var:

list=`ls dest_folder`

lsSondaki satırsonu karakterleri olmadan çıktısını saklıyorsunuz $list. lsyeni satır karakterleriyle ayrılmış dosya adları listesini çıkarır. newlinedosya adındaki herhangi bir karakter kadar geçerli bir karakter olduğundan çıktı güvenilir bir şekilde kullanılamaz. Mesela lsbir dizin için çıkış içerdiğini aveb bir dosya aynıdır a<newline>b.

 cd dest_folder

Bu komutun başarısız olup olmadığını kontrol etmiyorsunuz. Genel olarak komutların çıkış durumunu kontrol etmelisiniz, ancak bu özellikle doğrudur cd, çünkü komutların geri kalanı yeni dizinde olduğunuzu varsayar ve bu olmadığınızda dramatik sonuçlar doğurabilir.

cwd=`pwd`

POSIX kabukları, $PWDdeğişken içindeki geçerli dizinin (bir) yolunu zaten korur , bu nedenle kullanmanıza gerek yokturpwd burada (özellikle genel durumda komut ikamesi izleyen satırsonu karakterlerini yoldan kaldıracağından). Ayrıca, mvgöreli yolları kabul eder , böylece mutlak yolu oluşturmanıza gerek kalmaz.

for folder in $list;do

Bir değişkeni tırnaksız bırakmak kabuklardaki split + glob operatörüdür. Yani, değişkenin içeriği bölünür ( $IFSboşluklar için özel kurallarla belirtilen ayırıcılarda ) ve bu bölünmeden kaynaklanan her öğe, joker karakterler için aranır, böylece eşleşen dosyalar listesine genişletilebilirler.

Burada, bölmeyi istiyorsunuz, ancak sadece yeni satır karakterlerinde ve globbing'i istemiyorsanız, devre dışı bırakmanız gerekir:

 IFS='
 '; set -f
 for folder in $list
   mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}

Yine, bir değişkeni tırnaksız bırakmak split + glob operatörüdür. Burada, ikisini de istemezsiniz, bu yüzden bu değişkenleri belirtmeniz gerekir.

Daha önce de belirtildiği gibi, joker karakterler yalnızca alıntılanmadığında genişletilir. * . Daha önce globbing'i devre dışı bıraktıysanız set -f, set +fbu komutu çağırmadan önce eski durumuna getirmeniz gerekir .

Yazmanın çok daha iyi bir yolu:

cd dest_folder &&
  for folder in */;do
    mv -- "${folder}data/"* "$folder"
  done

Yine de birkaç not:

  • Bu, gizli klasörleri hariç tutar ve gizli dosyaları data klasörlerden .
  • İşlemde geçersiz kılınan dosyaları kontrol etmiyoruz ( -i seçeneğimv ).
  • Kullanarak */, dizinler arasında dolaşıyoruz sadece , ancak bu dizinlere sembolik bağlantılar da içeriyor. Bunu yapmak istemiyorsanız [ -L "${folder%/}" ] && continue, döngünün içine bir tane eklemeniz gerekir .
  • İçinde gizli olmayan bir klasör yoksa */kendi kendine genişler, bu nedenle mvadlı dosyayı bulamadığını söyleyerek hata mesajı alırsınız */data/*. Benzer şekilde, klasörlerin hiçbirinde gizli olmayan bir dosya yoksa, var olmayan bir hata iletisi alırsınız that-folder/data/*.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.