如何使用 bash 將所有檔案從多個目錄移至其父目錄

如何使用 bash 將所有檔案從多個目錄移至其父目錄

我有以下文件結構:

  • /首頁/數據/C01/目錄_WWE_346/file1.txt pic.jpg random.sh
  • /主頁/數據/C02/目錄_WWE_644/file1.txt pic.jpg random.sh
  • /首頁/數據/C03/dir_wwe_324/file1.txt pic.jpg random.sh

我希望他們是這樣的:

  • home/data/C01/file1.txt pic.jpg random.sh
  • home/data/C02/file1.txt pic.jpg random.sh
  • home/data/C03/file1.txt pic.jpg random.sh

它基本上是將多個文件向上移動一個目錄,我嘗試過這個腳本但沒有成功:

#!/bin/bash for i in */ do cd i/*/ mv * ../ done


發布此內容後(但在閱讀下面的重力響應之前),我意識到我沒有使用正確的變數擴展,並執行以下命令:

#!/bin/bash for i in */ do cd ${i}*wwe* mv * ../ done

該腳本將所有子目錄移至資料資料夾,所以我最終得到以下結果:

  • //C01/目錄_WWE_346/file1.txt pic.jpg random.sh
  • //C02/目錄_WWE_644/file1.txt pic.jpg random.sh
  • //C03/dir_wwe_324/file1.txt pic.jpg random.sh

    我究竟做錯了什麼?


附言。我編輯了這篇文章,以便它揭示了我所經歷的過程,而這樣的回應對於可能從這些回應中受益的新來者來說更有意義。感謝恩典,我學到了新事物。我一週前剛開始學習 bash,我感覺我正在進步。

答案1

  1. 變數只能透過前綴來識別和擴展$。如果循環定義了變數“i”,則需要使用$i每當你想要它的值時:

    for i in */; do
        cd $i/*/
    
  2. 「目前目錄」是進程範圍的,不會自動重置每個循環迭代。之後您需要手動返回父目錄:

    cd $i/*/; mv * ../; cd ../../
    

    或使用“子shell”來確定目錄更改的範圍:

    (cd $i/*/; mv * ../)
    
  3. 您沒有進行任何錯誤檢查。如果cd失敗了,後續的人mv就會做出不愉快的事。使用連接命令&&或執行相反的檢查並使用|| exit(或|| break),以看起來最好的為準:

    for i in */; do
        cd $i/*/ && {
            mv * ../;
            cd ../../
        }
    done
    
    for i in */; do
        cd $i/*/ || exit
        mv * ../
        cd ../../
    done
    
    for i in */; do
        (cd $i/*/ && mv * ../)
    done
    
  4. 改進:您可以將子目錄通配符移動到mv,即使有多個子目錄也可以正常工作:

    cd $i/ || exit
    mv */* .
    cd ../
    
  5. 改進:您可以做到這一點,cd根本不需要:

    mv $i/*/* $i/
    

相關內容