数値の順序を逆にしてファイル名を変更する

数値の順序を逆にしてファイル名を変更する

次のような名前のファイルがたくさんあります。

data1_1.txt
data1_2.txt
data1_3.txt
data2_1.txt
data2_2.txt
...

ただし、それらは逆順にダウンロードされ、名前が付けられます。結果が次のようにまとめて名前を変更するにはどうすればよいですか?

data1_3.txt
data1_2.txt
data1_1.txt
data2_2.txt
data2_1.txt
...

私の最初のアイデアは単にbash / zshスクリプトですが、うまく機能する他のツールがある場合は教えてください。

ベストアンサー1

そしてzsh

autoload zmv # best in ~/.zshrc

typeset -A c=()
zmv -n '(*)_<->.txt(#qnOn)' '$1_$((++c[${(b)1}])).txt-renamed' &&
  : zmv '(*)-renamed' '$1'

(必要に応じ-nて(ドライラン)を取り外し、:(ドライランなしで再実行する前に再初期化することを忘れないでくださいc=())。

  • <-><1-12>:10進範囲一致と似ていますが、ここでは境界が指定されていないため、1つ以上の10進数シーケンスが一致します。[0-9]##where ##is がzshERE と同じであると書くこともできます+
  • (#q...)~である明らかに構文の指定グローバル予選
  • n:数値順に並べ替え
  • On:名前に基づいて逆順にソートします。したがって、n上記の方法を使用すると、一致するファイルのリストを番号順に並べ替えることができます。
  • 交換するには、前の部分$1でキャプチャした内容を含めます。(*)_<digits>.txt
  • を追加します$((++c[${(b)1}]))。ここで、は$c以前に宣言された連想配列です。
  • ${(b)1}エスケープ付きのグローバル文字(エスケープがないと$1含まれていると正しく機能しません)。$1]
  • -renamedプロセスがファイルを上書きするのを防ぐために、2つのステップ(2番目のステップで削除されたサフィックスを追加)でこれを行います。

サンプルでは、​​以下を提供します。

mv -- data2_2.txt data2_1.txt-renamed
mv -- data2_1.txt data2_2.txt-renamed
mv -- data1_3.txt data1_1.txt-renamed
mv -- data1_2.txt data1_2.txt-renamed
mv -- data1_1.txt data1_3.txt-renamed

mv -- data1_1.txt-renamed data1_1.txt
mv -- data1_2.txt-renamed data1_2.txt
mv -- data1_3.txt-renamed data1_3.txt
mv -- data2_1.txt-renamed data2_1.txt
mv -- data2_2.txt-renamed data2_2.txt

技術的にはそうではありません。逆順でまたは、例のように数字が1ずつ増え、1から始まる場合にのみ実行します。[1, 2, 3]、、[4, 5, 6]すべて[0, 10, 20]に変わります[3, 2, 1]

そのリストを裏返すには少し複雑です。次のように見えます。

all_files=(*_<->.txt(n))
prefixes=(${all_files%_*})

for prefix (${(u)prefixes}) {
  files=(${(M)all_files:#${prefix}_<->.txt})
  new_files=(${(Oa)^files}-renamed)
  for old new (${files:^new_files})
    echo mv -i -- $old $new-renamed
}

(幸せなら削除echo)。

zmv '(*)-renamed' '$1'2番目の手順でやり直してください。

[0, 3, 10, 20]3番目の例として、追加のリストがある別の例では次のようになります。

mv -i -- data1_1.txt data1_3.txt-renamed
mv -i -- data1_2.txt data1_2.txt-renamed
mv -i -- data1_3.txt data1_1.txt-renamed
mv -i -- data2_1.txt data2_2.txt-renamed
mv -i -- data2_2.txt data2_1.txt-renamed
mv -i -- data3_0.txt data3_20.txt-renamed
mv -i -- data3_3.txt data3_10.txt-renamed
mv -i -- data3_10.txt data3_3.txt-renamed
mv -i -- data3_20.txt data3_0.txt-renamed

これらのソリューションは、ファイル名に含めることができる文字(または文字以外の文字)については想定していません_<digits>.txt。ベースのアプローチで起動しない限り、ファイル名を変更しません。後者のアプローチとは異なり、既存のサフィックスで名前付きファイルを上書きzmvするのを防ぎます(これが発生する前にメッセージが表示され-renamedますが)。または、サフィックスを追加する代わりに、名前が変更されたファイルをディレクトリに移動することもできます。-imv-renamedrenamed

おすすめ記事