正規表現の逆参照「名前変更」

正規表現の逆参照「名前変更」

私のディレクトリには「bar_foo.txt」というファイルがたくさんありますが、名前を「foo_bar.txt」に変更したいと思います。

の正規表現は、置換の逆参照検索に似ていますsedvim's/\(bar\)_\(foo\)/\2_\1/g'

  1. これを行う方法はありますかrename?パイプlsで接続できるいくつかのハッキングを見たことがありますが、明らかに驚くべきアプローチでsedbashありません。

  2. これを実行できる他のツールはありますか?

  3. 正規表現の「sedとvimスタイル」に名前はありますか?

答え1

renamePerl正規表現実装を使用している場合(Debian / Ubuntu / ...またはprenameArch Linuxなど)、$1また\1角括弧はバックスラッシュなしでキャプチャされます。

rename 's/(.*)_(.*)/$2_$1/' *_*

そうでない場合は、自分で実装する必要があります。

#! /bin/bash
for file in *_* ; do
    left=${file%_*}
    right=${file##*_}
    mv "$file" "$right"_"$left"
done

a_b_c注:作成したとおり、2つのコマンドの名前がに変更されましたc_a_b。 getを実行するには、b_c_a最初のキャプチャグループを.*?(最初の場合)に変更し、2番目の場合は最初のキャプチャグループをおよびに%変更%%します###

答え2

これを行うための標準ツールは次のとおりですpax。しかし、直接移動するよりもハードリンクとコピーを使用する方がうまくいきます。もちろん、すべてのタスクはデフォルトで新しいリンクを作成し、古いリンクを削除します。

私はステップから抜け出すことを好みます。今、比較し、対照的に同じツリーの2つのコピーがあります。これは、ファイル名を動的に変更する場合に特に重要です。ファイル名の編集操作の結果は、既存のリンク名と同じにすることができます。この場合、どのファイルにその名前がありますか?

したがって、POSIXlyで行うには、次のようにします。

pax -rwls'|^\(bar\)_\(foo\).txt$|\2_\1.txt|' -s'|.*||' *_*.txt .

完了すると、関連ファイルへの個々のリンクが生成されます。結果が要件と一致することを確認し、前の結果を削除します。

また、正規表現スタイルが標準ですsedvim着替える

答え3

  1. とともにユーティリティLinuxrenameいいえ、これは基本的な文字列置換のみを行います。 Perlベースの場合はいrename、以下を参照してください。ジョロバの答え

  2. zshの使用zmv:

    autoload -U zmv      # put this in your ~/.zshrc
    zmv '(*)_(*).(*)' '${2}_$1.$3'
    zmv -w '*_*.*' '${2}_$1.$3'
    

    上記の2つの呼び出しはzmv同じです。サブディレクトリで操作を実行するには、次のものを使用できます。zmv -w '**/*_*.*' '$1/${3}_$2.$4'

  3. Vi(m)とsed(拡張)の使用基本正規表現。また、見ることができます私の正規表現がXでは動作しますが、Yでは動作しないのはなぜですか?

関連情報