Bashスクリプトを使用して同じディレクトリ内の複数のファイルの名前を変更したい。ファイルの名前は次のとおりです。
file2602201409853.p file0901201437404.p file0901201438761.p file1003201410069.p file2602201410180.p
次の形式に名前を変更します:
file2503201409853.p file2503201437404.p file2503201438761.p file2503201410069.p file2503201410180.p
renameコマンドについて読んでいて、この方法で実行しようとしましたが、何も実行されません。構文について質問があると思います。次に、次のように 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
は冗長であることを意味しますが、そうではありません。 何でも)ファイル名を使用して:
$ 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
コメント
- 注これはDebianおよび派生物(Ubuntu、Mint、…)でのPerlの名前変更です。他のLinuxディストリビューションでは、
rename
は完全に異なるファイル名前変更ツールです(Debianはrename.ul
として出荷されます)。 - そのようなツールがディストリビューションにない場合は、@ MichaelCampbellの回答をご覧ください。すべての分配法則は、debianのようにデフォルトの
rename
を置き換えると思います。
回答
これでうまくいくはずです:
for f in file*; do mv $f ${f/${f:4:8}/25032014}; done
4番目と12番目の文字の間の文字列を「25032014」に置き換えます。
コメント
- この
for f in file*; do mv $f ${f/${f:4:4}/2503}; done
も機能します。 - その'いいですね。単語の置換のために通常の単語を実行したいだけの場合は、sedのように機能します。例えば
for f in *Huge*; do mv $f ${f/Huge/Monstrous}; done
- @ Eric- 'の方が明確でエレガントだと思うので、代わりに回答を投稿しました。回答として投稿したい場合は、'削除します。ありがとうございます!
- 二重引用符がないのはなぜですか?
- エラーが発生します:" mv:ターゲット' FILE_NAME 'はディレクトリではありません"
回答
これは本当に@Ericの上記の回答ですが、エレガントな回答なのでより多くの注目を集めるために、適切な回答として再投稿しています。
for f in *Huge*; do mv "$f" "${f/Huge/Monstrous}"; done
回答
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コマンドを渡す習慣はありません-書かれているように、ただのエコーです。あなた」動作する前にそれを整理する必要があります。
回答
ループせずにそれを行う簡単なネイティブの方法で、 ディレクトリトラバーサル:
find -type f | xargs -I {} mv {} {}.txt
すべての名前が変更されますファイルを配置します。
そして作品の下並列化の例:
find -name "file*.p" | parallel "f="{}" ; mv -- {} ${f:0:4}2503${f:8}"
コメント
- より良い解決策を想像するのは簡単な最初のアプローチでした。動作するコマンドが必要な場合は、次のようにします。
-
find -type f -name "file*.p" | parallel 'ext="{}" ; mv -- {} ${ext:0:4}2503${ext:8}'
回答
この種のことを頻繁に行う場合は、「rename.pl」を検索してください。これはperlスクリプトですが、perlコード(as ///式など)を入力するだけで、その式またはコードに基づいて一括名前変更が行われます。
基本バージョンがあります。ここ: http://stackoverflow.org/wiki/Rename.pl ですが、他のバージョンがネット上に浮かんでいます。それは何年も前からありました。
*
がどこにあると思いましたか?