特定のファイルグループをBashの特定のフォルダグループに移動する

特定のファイルグループをBashの特定のフォルダグループに移動する

たとえば、次のファイルセットを移動したい場合Chapter1_sectionXをbook/chapter1などの特定のフォルダにそしてChapter2_sectionXから本/chapter2へなど。私は現在このアプローチを使用していますが、非効率的だと思います。

touch chapter{1,2}_section{1..4}.odf
mkdir -p book/chapter{1,2}
mv chapter1_section* book/chapter1
mv chapter2_section* book/chapter2

使用せずにこれを行うより短い方法はありますか?~のためリング?

答え1

forループを使用しませんか? Perlユーティリティ(rename一部のディストリビューションでは、prenameまたfile-renameはとも呼ばれるperl-rename)を使用してサブディレクトリを作成し、その中にファイル名を変更できます。たとえば、

$ rename -v 'BEGIN{mkdir "book"};
             if (m/chapter(\d+)/) {
               my $d="book/chapter$1";
               mkdir $d;
               $_ = "$d/$_"
             }' *
chapter1.txt renamed as book/chapter1/chapter1.txt
chapter2.txt renamed as book/chapter2/chapter2.txt
chapter3.txt renamed as book/chapter3/chapter3.txt
chapter4.txt renamed as book/chapter4/chapter4.txt
chapter5.txt renamed as book/chapter5/chapter5.txt

スクリプトの英語の要約:

現在のファイル名($_)が正規表現と一致する場合は、ファイル名chapter(\d+)から章番号を抽出し(つまり$1、正規表現の最初で唯一のキャプチャグループです(\d+))、その章のディレクトリを作成してから、現在のファイルの名前を次のように変更します。 。礼拝の規則。

一致しないファイル名は無視されます。

renamePerlは、名前変更スクリプトが.perl値を変更した場合にのみファイルの名前を変更しようとします$_。また-f、このオプションを使用して、強制的に使用しない限り、既存のファイルの上書きを拒否します。

Perlの名前変更を使用すると、次のことができます。どのスクリプト内のPerlコードの名前を変更します(ただしプラグマがuse strict適用されるため、変数を宣言する必要があります)。コードが変更されると、$_ファイル名が変更されます。そうでなければそうではありません。

まず、テスト実行を実行し、-n名前変更が必要に応じて機能することを確認するのが最善です(間違ったバッチの名前変更から回復することは主要なPITAになる可能性があります)。 -nファイル名を変更せずに内容のみを表示します。会議する。詳細な出力のために(上記と同じ)-nに置き換える-vか、-n自動操作のために削除してください。

答え2

私はこのmmvユーティリティが次の作業に便利だと思います。

$ mmv -v 'chapter*_section*.odf' 'book/chapter#1/'
chapter1_section1.odf -> book/chapter1/chapter1_section1.odf : done
chapter1_section2.odf -> book/chapter1/chapter1_section2.odf : done
chapter1_section3.odf -> book/chapter1/chapter1_section3.odf : done
chapter1_section4.odf -> book/chapter1/chapter1_section4.odf : done
chapter2_section1.odf -> book/chapter2/chapter2_section1.odf : done
chapter2_section2.odf -> book/chapter2/chapter2_section2.odf : done
chapter2_section3.odf -> book/chapter2/chapter2_section3.odf : done
chapter2_section4.odf -> book/chapter2/chapter2_section4.odf : done

与える

$ tree book
book
├── chapter1
│   ├── chapter1_section1.odf
│   ├── chapter1_section2.odf
│   ├── chapter1_section3.odf
│   └── chapter1_section4.odf
└── chapter2
    ├── chapter2_section1.odf
    ├── chapter2_section2.odf
    ├── chapter2_section3.odf
    └── chapter2_section4.odf

2 directories, 8 files

答え3

完全性を確保するために、ファイル名と宛先ディレクトリ名の単純な構造のため、次のコマンドfindはすべての章ファイルを繰り返し、ファイル名から名前が由来する宛先ディレクトリに移動します。

find . -maxdepth 1 -type f -name 'chapter*_section*.odf' -exec bash -c 'f={}; d="book/${f%_*}"; mv "$f" "$d"' \;

これは、一致するすべてのファイルを(暗黙的に)繰り返し、chapter*_section*.odfファイル名から最後のコンポーネントを削除して、ターゲットディレクトリ名を派生するシェルコマンドを実行し、その部分のみを効果的に保持します。次に、現在処理されているファイルをそのサブディレクトリに移動します。_*chapterNbook/

ノート

  • この-maxdepth 1オプションは、現在のディレクトリを処理した後にターゲットディレクトリに移動されたファイルに対して繰り返し操作を実行するのではなく、現在のディレクトリ内のファイルに対してのみ操作を実行させることに関連しています。
  • {}viaという名前のシェルコマンドに含まれています。-exec落胆しかし、マルウェアを挿入しようとしないと動作します。

関連情報