web-dev-qa-db-ja.com

`rename`正規表現の後方参照

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

sedvimでは、これに対する正規表現は's/\(bar\)_\(foo\)/\2_\1/g'のようになり、置換で検索を逆参照します。

  1. renameでこれを行う方法はありますか? lsからsedからbashにパイプするハックを見たことがありますが、それは明らかに驚くべき方法ではありません。

  2. これを行う別のツールはありますか?

  3. 正規表現の「sedとvimフレーバー」の名前はありますか?

4
lindhe

Perl正規表現を使用したrename実装がある場合(Debian/Ubuntu /…、またはArchLinuxではprename)、$1の代わりに\1が必要です。また、括弧のキャプチャに円記号はありません。

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

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

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

注:記述されているように、両方のコマンドはa_b_cの名前をc_a_bに変更します。 b_c_aを取得するには、最初のケースで最初のキャプチャグループを.*?に変更するか、%%%に、###に変更します。二つ目。

4
choroba
  1. til-linux rename の場合、いいえ、これは基本的な文字列の置換のみを行います。 Perlベースのrenameでは、はい、 chorobaの答え を参照してください。

  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では機能しないのはなぜですか?

これを行う標準ツールはpaxですが、直接移動するよりもハードリンクとコピーの方がうまく機能します。もちろん、すべての動きは、基本的に、新しいリンクを作成し、古いリンクを削除することです。

私はこれらの手順を解除することを好みます-同じツリーのコピーが2つあり、比較対照できる間、少しの間です。これは、ファイルの名前を動的に変更する場合に特に重要です。ファイル名に対する編集操作の結果が既存のリンク名と同じになる可能性があります。その場合、どのファイルに名前が付けられますか?

そして、POSIXlyに尋ねられたとおりに行うには、次のことができます。

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

結果は、問題のファイルへの個別のリンクになります。結果が希望どおりであることを確認し、古い結果を削除します。

そして、sedvim正規表現スタイルは標準です [〜#〜] bre [〜#〜]

0
mikeserv