ディレクトリ内の複数のファイルの名前を同時に変更する方法


12

/var/tmp/abc4つのファイルがあるディレクトリsay があります。

12345-ram-3e3r5-io9490-89adu9.csv
45434-dam-qwe35-to9490-43adu9.csv
11234-cam-yy3r5-ro9490-85adu9.csv
14423-sam-hh3r5-uo9490-869du9.csv

私はすべてのCSVファイルの名前を変更する(すべてのファイルを見つけて名前を変更する)ために、できるだけ短い(おそらく1ライナー)方法で:

XXXXX-ram-3e3r5-io9490-89adu9.csv
XXXXX-dam-qwe35-to9490-43adu9.csv
XXXXX-cam-yy3r5-ro9490-85adu9.csv
XXXXX-sam-hh3r5-uo9490-869du9.csv

回答:


15

rename -n 's/(\w+)/XXXXX/' *.csv

-n幸せなときに削除します。


2
の適切なバージョンの場合rename。これは、Debian renamerenameパッケージおよび派生物(およびprenameRedHat説得のシステム上のIIRC )からのLarry Wallのものだ と思います。非常に便利なツール。
キセノイド

2
perl-rename
Arch

1
@SHawarden、コマンドを実行し、manページの関連部分を読んで置換パターンを理解しようとしましたが、verboseフラグを追加すると、何も出力せず、現在のパスがに類似した名前のファイル12345_foo.csv。動作させるために追加のタスクを実行する必要がありますか(現在Fedora 30で)?ループよりもクリーンなアプローチです。前もって感謝します!
danieldeveloper001

3
@ danieldeveloper001を使用しましたrenameprename?上記の私のコメントを参照してください。man {the command}最後に著者をリストします。
キセノイド

2
これはDebianから派生したシステムでのみ機能します。 Fedoraから派生したシステムには、まったく異なるrenameコマンドがあります。参照unix.stackexchange.com/a/238862/135943
ワイルドカード

11

試してください:

for f in *.csv; do mv -i -- "$f" "XXXXX-${f#*-}"; done

使い方:

  • for f in *.csv; do

    これにより、すべての*.csvファイルのループが開始されます。

  • mv -i -- "$f" "XXXXX-${f#*-}"

    これにより、必要に応じてファイルの名前が変更され、ファイルを上書きする前に対話形式で要求されます。

  • done

    これはループの終わりを示します。

例:

$ ls -1
11234-cam-yy3r5-ro9490-85adu9.csv
12345-ram-3e3r5-io9490-89adu9.csv
14423-sam-hh3r5-uo9490-869du9.csv
45434-dam-qwe35-to9490-43adu9.csv
$ for f in *.csv; do mv -i -- "$f" "XXXXX-${f#*-}"; done
$ ls -1
XXXXX-cam-yy3r5-ro9490-85adu9.csv
XXXXX-dam-qwe35-to9490-43adu9.csv
XXXXX-ram-3e3r5-io9490-89adu9.csv
XXXXX-sam-hh3r5-uo9490-869du9.csv

4

あなたが投稿した小さな挑戦が好きだったので、ここに私の解決策があります。すべてのファイルが5つの数字で始まると仮定しているため、cutコマンドを使用しますをして、最初の数字ファイルを「XXXXX」に置き換えます。

以下、コマンドの前のファイル。

-rw-rw-r--. 1 daniel daniel 0 May 13 23:18 11111_bar_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 12345_baz_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 67890_foo_file.xml

以下は、1つのライナーコマンドです。

for src in *.csv; do dst=XXXXX$(echo $src| cut -c6-); mv $src $dst; done;

以下は、コマンドの後のファイルです。

-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 67890_foo_file.xml
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 XXXXX_bar_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 23:18 XXXXX_baz_file.csv

それはあなたが探しているものですか?:)

参照:

bashのコマンド出力をループする

bashのサブストリング


2
Bashはこの種の文字列操作を行うことができ、それぞれに新しいプロセスをフォークする必要はありません。他の方法で答えてください。
chx

1
@chx、すでに他の回答を見て、そこから少し知識を習得しましたが、指摘してくれてありがとう。詳しく説明していただけますno need to fork a new process for eachか?
danieldeveloper001

3
cut別のバイナリ(/usr/bin/cut)であり、それを実行すると、シェルの組み込みを使用するよりも多くのリソースが消費されます。
chx

2
私は、意図が多くのファイルの名前を変更するかどうかは実際に重要です。明確化していただきありがとうございます!
danieldeveloper001

1

フォークなし:

ls | perl -lne '$suf=substr($_,6); rename $_, "XXXXX-$suf"'

シェルループを使用する場合、mvファイルごとに1回分岐します。Perlのrenameコマンドはしていません。

(Perlのrenameコマンドにはいくつかの制限がありますが、この特定のケースではそれらの制限は適用されません。)

については rename前に示しコマンド、はい、機能しますが、2つの異なる種類の名前変更などの間で混乱が生じます。適切なものがあれば素晴らしいですが、そうでなければ、これも機能します。

perl-renameコマンドがなく、インストールできない場合は、次のようにします。

ls | perl -lne '$old=$_; s/(\w+)/XXXXX/; rename $old, $_'

ご覧のとおり、これは一番上の回答に示されているものと同じ置換を使用しています。もちろんperlのリネームは(トップ答えは、言及された他の添えものを持って-n、すでにそこだ-0-fなど)、およびより多くのそれらのあなたが必要とする、より多くのあなたは、このように代わりに、独自の圧延のことをインストールする必要があります。


パイプの通常の実装にはフォークがあります。
ムル

私は、「mv」が/ usr / bin / mvなどをフォークするシェルでさえも、「名前を変更するファイルごとに一度フォークしない」ことを意味していました。これは、「rename」コマンドがlibcで直接rename()を呼び出すperl内部コマンドであるためです。もちろん、いくつかの制限がありますが、この特定の例では、これらの制限は適用されません。
シタラム

1
これはrenameコマンドにも当てはまります(トップアンサー、Perlも使用します)ので、単に「ノーフォーク」よりも少し説明を追加する必要があります。
ムル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.