Linuxシステムで処理する必要があるファイルがたくさんあります。ファイルは次のようになります。
2009-08-18T034353_DR1_4N-NAC_123456_1234_band1.ntf
2009-08-18T034353_DR1_4N-NAC_123456_1234_browse.jpg
2009-08-18T034353_DR1_4N-NAC_123456_1234_band2.ntf
2009-08-18T034353_DR1_4N-NAC_123456_1234_license.txt
2009-08-18T034353_DR1_4N-NAC_123456_1234_metadata.xml
2009-08-18T034353_DR1_4N-NAC_123456_1234_readme.txt
2009-08-18T034353_DR1_4N-NAC_123456_1234_udm.tif
この部分を取り除きたいです。-NAC_123456_1234
最初の部分は英数字で構成でき、数値部分は数字のみで構成できます。
名前変更コマンドを試しましたが、機能しませんでした。私は次のようなことを考えました。
rename '/-[a-zA-Z]+_[0-9]+_[0-9]+//' *.*
私が何を見逃しているのかを調べるのに役立つ人はいますか?
私の名前が変更されたバージョンは次のとおりです。
rename from util-linux 2.23.2
答え1
使用したい構文はPerlrename
コマンド用です。オペレーティングシステムによっては、このオプションをprename
使用することもインストールすることもできますが、perl-rename
このオプションが必要です。いいえfromは試行中の正規表現構文をrename
使用します。util-linux
そしてこれにもかかわらず、少し違うものが必要です。
perl-rename 's/-[a-zA-Z]+_[0-9]+_[0-9]+//' *.*
実際に欲しいのは、最後の項目以降のすべての項目を削除することです-
。
perl-rename 's/(.*)-(.*)(\.*)/$1$2/' *.*
ただし、このツールを使用する必要はありません。小さなシェルループを実行できます。
for file in *; do
ext="${file##*.}"
newName="${file%-*}.$ext"
echo mv -- "$file" "$newName"
done
これは実行されるコマンドのみを印刷します。満足したら、正しい場合は削除してecho
再度実行して、実際に名前を変更してください。
説明する
for file in *
:現在のディレクトリ内のすべてのファイル(およびディレクトリ)を繰り返して、各ファイルを$file
。ext="${file##*.}"
: 構文は${variable##pattern}
先頭から最長の一致を削除します。したがって、ここではファイル拡張子を残し、最後のファイルまですべてを削除します。pattern
$variable
.
newName="${file%-*}.$ext"
${variable%pattern}
: 構文が の末尾から削除する最も短い一致です。だからここでは最後まですべてを私たちに任せます。次に、拡張子を追加して新しいファイル名を指定します。pattern
$variable
-
mv -- "$file" "$newName"
:ファイル名を変更します。
答え2
ある場合は、zsh
そこで実行する方が簡単で安全で移植性に優れています。
autoload -Uz zmv
zmv -n '(*-)[[:alnum:]]##_<->_<->(*.*)' '$1$2'
(-n
満足した場合は削除(模擬実行))。
これはextendedglob
正規表現の代わりにシェルグローブ(zshサポート)を使用しますが、機能に関しては拡張正規表現と同じです。
*
通常、任意の数の文字(または有効な文字を形成しないバイトがある場合はバイト)と一致します。これが(ほとんどの)正規表現よりも安全な理由の1つです。[[:alnum:]]
POSIX 文字クラスの標準一致です。##
1つ以上の前の原子(例えば、+
ERE / PCREの原子)。<->
1つ以上のASCII 10進数で構成される任意のシーケンスに似ています<1-10>
が、制限はありません。
zmv
名前の変更を開始する前に、いくつかの完全性チェックが実行され、rename
周囲のさまざまなバリエーションよりも安全です。