Bashスクリプトを使用して、同じディレクトリにある複数のファイルの名前を変更したい。ファイルの名前は次のとおりです。
file2602201409853.p
file0901201437404.p
file0901201438761.p
file1003201410069.p
file2602201410180.p
次の形式に名前を変更したい:
file2503201409853.p
file2503201437404.p
file2503201438761.p
file2503201410069.p
file2503201410180.p
名前変更コマンドについて読んでいて、このようにしてみましたが、何もしません。構文について質問があると思います。次に、次のように mv コマンドを使用してループを作成できると読みました:
for file in cmpsms*2014*.p; do
mv "$file" "${file/cmpsms*2014*.p/cmpsms25032014*.p}"
done
しかし、ファイルの名前を変更することはできません。何が悪いのですか?
最初に名前を変更することを検討するのは正しかった。正規表現に慣れていない場合、構文は少し奇妙ですが、何をしているのかがわかっていれば、これは最速/最短のルートです。
rename 's/\d{4}/2503/' file*
これは単に最初の4つの数値と一致し、指定した数値と交換します。
そしてテストハーネス(-vn
は、冗長であることを意味しますが、ファイル名を使用してdo何もしないでください):
$ rename 's/\d{4}/2503/' file* -vn
file0901201437404.p renamed as file2503201437404.p
file0901201438761.p renamed as file2503201438761.p
file1003201410069.p renamed as file2503201410069.p
file2602201409853.p renamed as file2503201409853.p
file2602201410180.p renamed as file2503201410180.p
これでうまくいくはずです:
for f in file*; do mv $f ${f/${f:4:8}/25032014}; done
4番目と12番目の文字の間の文字列を「25032014」に置き換えます。
これは本当に上から@Ericの回答です-しかし、それはエレガントな回答なので、より注目を引くために適切な回答として再投稿しています。
for f in *Huge*; do mv $f ${f/Huge/Monstrous}; done
ディレクトリトラバーサルを使用して、ループせずにそれを行う簡単なネイティブな方法:
find -type f | xargs -I {} mv {} {}.txt
すべてのファイルの名前を変更します。
そしてparallelizationを使用した作業例の下に:
find -name "file*.p" | parallel 'f="{}" ; mv -- {} ${f:0:4}2503${f:8}'
ptrn='file[0-9][0-9][0-9][0-9]2014[0-9][0-9][0-9][0-9][0-9].p'
path=/dir
( set -- "${path}/"${ptrn} ; for f ; do {
echo "mv ${path}/${f} \
${path}/file25032014${f#2014}"
} ; done )
これでうまくいくはずです。注意-私は大量のmvコマンドを渡す習慣はありません-書かれているように、それは単なるエコーです。それが機能する前に、それを整理する必要があります。
このようなことを頻繁に行う場合は、「rename.pl」を検索してください。これはPerlスクリプトですが、Perlコード(s ///式のような)を単純に与えることができ、その式またはコードに基づいて大量の名前変更を行います。
ここには基本的なバージョンがあります: http://stackoverflow.org/wiki/Rename.pl ですが、ネット上に浮かんでいる他のバージョンがあります。それは古くからあり、古くからありました。