bashスクリプトのファイルをファイル名から抽出したサブディレクトリに移動します。

bashスクリプトのファイルをファイル名から抽出したサブディレクトリに移動します。

次のバックアップファイルを含むディレクトリがあります。

projectA20210901.gz
projectA20210902.gz
projectB20210901.gz
projectB20210902.gz

projectA*まだ存在しない場合は、すべてのファイルを移動してサブディレクトリを作成したいと思います。./projectA/projectB*./projectB/

日付より前のプロジェクト名は2021...さまざまで、ファイル名から抽出する必要がありますが、日付は常にあり、常に2022021、2022などで始まります。 2029年以降に何が起こるのか心配する必要はありません。

パラメータ拡張サブディレクトリ名になるプロジェクト名を抽出するために使用できます。

$ string=projectA20211103-23.gz
$ echo ${string%202*}
projectA

現在のディレクトリ内のすべてのファイルで実行されるように、これをスクリプトにどのように配置できますか?フォルダとシンボリックリンクは無視する必要があります。

答え1

最初のステップが良いです。findBashシェルでこれを使用して、次のように結果をパイピングしてみてください。

$ find . -maxdepth 1 -iname "project?202?????.gz" -print0 | xargs -0 -I {} bash -c '
        var="$1";
        var1="${var%%202*}";
        mkdir -p "$var1";
        echo mv "$var" "$var1"' xargs_bash {}

mv ./projectB20210901.gz ./projectB
mv ./projectA20210901.gz ./projectA
mv ./projectB20210902.gz ./projectB
mv ./projectA20210902.gz ./projectA

コメント:

  • 上記の内容を一行に記入してください。
  • mv出力が実行したいコマンドと一致すると判断した場合は、実行したい移動行から「echo」コマンドを削除するだけです。
  • 私は簡潔さを目指していません。私は読みやすさが好きです。

仕組み:

  • find現在のディレクトリを見て、そこからツリーの下に作業します。
  • -maxdepth 1検索を現在のディレクトリに制限するように、つまりツリーの下に検索しないように find に指示します。
  • -iname次のパターンに従って大文字と小文字を区別せずにファイル名を見つけます。
  • ファイル名パターンは特殊文字を使用します。 ?すべての文字を表し、*任意の数の文字を表します。
  • print0出力では、各結果の末尾に標準の改行文字の代わりに \0 ヌル文字を配置します。これは、ファイル名に改行文字が含まれる場合があることを考慮したものです。
  • xargs -0パイプが出力の各ファイル名が次のファイル名とヌル文字で区切られていることを認識した後
  • xargs bash -c '...'find文字列操作に基づいて必要に応じて各出力を処理し、必要に応じてサブディレクトリを作成し(mkdir -p)、最後に要求時に各ファイルをサブディレクトリに移動するように機能するbashシェルを作成します。

したがって、cmdがない最後の行は次echoのようになります。

 $ find . -maxdepth 1 -iname "project?202?????.gz" -print0 | xargs -0 -I {} bash -c 'var="$1"; var1="${var%%202*}"; mkdir -p "$var1"; mv "$var" "$var1"' xargs_bash {}

HTH。

答え2

別の方法は次のとおりです。

cd /mybackups
for file in *;
do
    if [ -f "$file" ]; then
        newdir=${file%202*}
        mkdir -p "$newdir"
        mv "$file" "${newdir}"
    fi
done

関連情報