bash端末を使用して式をキャプチャする方法は?

bash端末を使用して式をキャプチャする方法は?

log_<date>.txtネストされたディレクトリに散在している同じ命名法を共有するファイルがありますroot<date>ファイルがYYYYmmddHHMM形式で生成された日付はどこにありますか?コード互換性の問題のため、すべてのファイルの名前を次のように変更したいと思います。<date>_log.txt

式をキャプチャする必要があることを知っていますが、<date>Bashではどうすればよいですか?また、入れ子になったディレクトリでこれをどのように実行しますか?

ベストアンサー1

シェル変数にこれらのファイルの1つの名前があるとしますnamelog_次に、完了を使用して変数値から対応するビットを削除し、完了を使用して${name#log_}ビット.txtを削除します${name%.txt}。残りは日付であり、その形式は本質的に興味深いものではありません。削除された値を取得し、_log_.txt最後に追加して新しい名前を作成するのは簡単です。

単一のディレクトリにあるファイルに対してこれを行うには、ループを使用します。変数値の先頭にあるディレクトリ名も削除する必要があります。

shopt -s nullglob

for name in root/log_*.txt; do
    newname=root/${name#root/log_}    # remove prefix, add root/ back
    newname=${newname%.txt}_log.txt   # remove suffix, add _log.txt back

    printf 'Would move "%s" to "%s"\n' "$name" "$newname"
    # mv -i "$name" "$newname"
done

mv安全のため、実際のコマンドをコメントアウトしました。まず、何が起こるかを確認するには、一度テストを実行する必要があります。

シェルオプションはシェルを作成しnullglobます。bash削除する拡張されていないままにするのではなく、一致しないパターン。これはlog_*.txt、指定されたディレクトリにファイルがないとループがまったく実行されないことを意味します。

これは、現在のディレクトリを含むすべてのファイルに再帰的に適用できます。ややループのパターンを修正してください。

shopt -s globstar nullglob

for name in ./**/log_*.txt; do
    dirpath=${name%/*}                      # get path of directory
    newname=$dirpath/${name#$dirpath/log_}  # remove prefix, add directory path back
    newname=${newname%.txt}_log.txt         # remove suffix, add _log.txt back

    printf 'Would move "%s" to "%s"\n' "$name" "$newname"
    # mv -i "$name" "$newname"
done

他の変更には、サブディレクトリを一致させることができるglobstarシェルオプションの有効化が含まれます**。また、新しい名前の前に追加できるようにディレクトリパスを選択しました。

findループへの入力を生成するためにも使用できます。

find . -type f -name 'log_*.txt' -exec sh -c '
    for name do
        dirpath=${name%/*}                      # get path of directory
        newname=$dirpath/${name#$dirpath/log_}  # remove prefix, add directory path back
        newname=${newname%.txt}_log.txt         # remove suffix, add _log.txt back

        printf "Would move \"%s\" to \"%s\"\n" "$name" "$newname"
        # mv -i "$name" "$newname"
    done' sh {} +

これは、現在のディレクトリまたは次のディレクトリで名前が一致するすべての一般ファイルを検索し、デフォルトで上記の2番目のバリエーションのループと同じ操作を実行するlog_*.txtインラインスクリプトに一括渡します。sh -c

おすすめ記事