Bashスクリプトを使用して複数のファイルの名前を変更する

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 

しかし、ファイルの名前を変更できません。何が間違っているのですか?

コメント

  • の重複の可能性正規表現を使用するファイルの数は?
  • 'パラメータ展開置換式の右側にパターン式を含めることはできません。その*がどこにあると思いましたか?
  • @Kiwyその質問は、ファイル名の一部を削除することに関するものです。エルゴ、非常に疑わしい重複です。
  • 次回は、ファイル名の変更について説明してください(相違点と類似点を確認する前に、しばらくの間これを確認する必要がありました)。例は良いですが、説明の例はさらに優れています。

回答

最初に名前の変更を検討するのは正しかった。正規表現に慣れていない場合、構文は少し奇妙ですが、何をしているのかがわかれば、はるかに高速/最短のルートです。

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 ですが、他のバージョンがネット上に浮かんでいます。それは何年も前からありました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です