bash を使用して複数のディレクトリからすべてのファイルを親ディレクトリに移動する方法

bash を使用して複数のディレクトリからすべてのファイルを親ディレクトリに移動する方法

ファイル構造は次のとおりです。

  • /ホーム/データ/C01/翻訳元/file1.txt pic.jpg ランダム.sh
  • /ホーム/データ/C02/翻訳元/file1.txt pic.jpg ランダム.sh
  • /ホーム/データ/C03/翻訳元/file1.txt pic.jpg ランダム.sh

私はこうありたいと願っています:

  • home/data/C01/file1.txt pic.jpg ランダム.sh
  • home/data/C02/file1.txt pic.jpg ランダム.sh
  • home/data/C03/file1.txt pic.jpg ランダム.sh

基本的には複数のファイルを 1 つのディレクトリ上に移動するのですが、このスクリプトを試しましたが成功しませんでした。

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


これを投稿した後 (ただし、以下の grawity の応答を読む前)、適切な変数展開を使用していないことに気づき、これを実行しました。

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

スクリプトはすべてのサブディレクトリをデータ フォルダーに移動するため、最終的には次のようになります。

  • //C01/翻訳元/file1.txt pic.jpg ランダム.sh
  • //C02/翻訳元/file1.txt pic.jpg ランダム.sh
  • //C03/翻訳元/file1.txt pic.jpg ランダム.sh

    何が間違っているのでしょうか?


追伸: 投稿を編集して、私が経験したプロセスを明らかにし、これらの回答から恩恵を受ける可能性のある新参者にとって回答がより意味を成すようにしました。grawity さん、ありがとうございます。新しいことを学びました。1 週間前に bash を学び始めたばかりですが、進歩していると感じています。

答え1

  1. 変数はプレフィックスでのみ認識され、展開されます$。ループで変数「i」を定義する場合は、$iいつでも値を確認したいときは:

    for i in */; do
        cd $i/*/
    
  2. 「現在のディレクトリ」はプロセス全体にわたるため、ループの繰り返しごとに自動的にリセットされるわけではありません。その後、手動で親ディレクトリに戻る必要があります。

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

    または、「サブシェル」を使用してディレクトリ変更の範囲を指定します。

    (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/
    

関連情報