私のディレクトリには「bar_foo.txt」というファイルがたくさんありますが、名前を「foo_bar.txt」に変更したいと思います。
の正規表現は、置換の逆参照検索に似ていますsed
。vim
's/\(bar\)_\(foo\)/\2_\1/g'
これを行う方法はありますか
rename
?パイプls
で接続できるいくつかのハッキングを見たことがありますが、明らかに驚くべきアプローチでsed
はbash
ありません。これを実行できる他のツールはありますか?
正規表現の「sedとvimスタイル」に名前はありますか?
答え1
rename
Perl正規表現実装を使用している場合(Debian / Ubuntu / ...またはprename
Arch 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 .
完了すると、関連ファイルへの個々のリンクが生成されます。結果が要件と一致することを確認し、前の結果を削除します。
また、正規表現スタイルが標準ですsed
。vim
着替える
答え3
とともにユーティリティLinux
rename
いいえ、これは基本的な文字列置換のみを行います。 Perlベースの場合はいrename
、以下を参照してください。ジョロバの答え。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'
Vi(m)とsed(拡張)の使用基本正規表現。また、見ることができます私の正規表現がXでは動作しますが、Yでは動作しないのはなぜですか?