次の名前の複数のファイルを含むディレクトリがあります。
- 一般名 - dd-01_.txt
- 一般名 - dd-02_.txt
- 一般名-dd-03_.txt
- 一般名 - dd-04_.txt
次のように番号と拡張子だけを維持しながら、すべての名前を変更したいと思います。
- 01.txt
- 02.txt
- 03.txt
- 04.txt
シェルスクリプトを使用してこれをどのように実行できますか?
答え1
パールの名前を変更する
私は(perl-)renameを使います。ディストリビューションには 2 種類の名前変更が用意されているため、Perl バージョンの名前変更がインストールされていることを確認できます。
$ rename --version
perl-rename 1.9
これを実行して、-n
「テスト実行」でコマンドをテストします。
$ rename 's/[^0-9]*([0-9]*).*/\1.txt/' * -n
generic name- dd -01 _.txt -> 01.txt
generic name- dd -02 _.txt -> 02.txt
generic name- dd -03 _.txt -> 03.txt
generic name- dd -04 _.txt -> 04.txt
満足したら、コマンド自体を実行してください。
$ rename 's/[^0-9]*([0-9]*).*/\1.txt/' *
説明する
rename 's/foo/bar/' *
:すべてのファイルの名前を変更*
します()。正規foo
表現をbar
。[^0-9]*([0-9]*).*
[^0-9]*
:「キャプチャグループ」に含まれる数字の後に([0-9]*)
残りの文字が続く数字ではなく、すべての文字と一致します.*
。これは完全なファイル名と一致します。\1.txt
:ファイル名をキャプチャされたグループに\1
変更します.txt
。
別の名前を変更する
より簡単な名前変更をインストールした場合は、同様の内容が表示されます。
$ rename --version
rename from util-linux 2.33.1
この場合、次の2つのコマンドを使用できます。
$ rename 'generic name- dd -' '' *
$ rename ' _' '' *
しかし、私はperl-renameを学ぶことを強くお勧めします。
答え2
以下のパッドのいずれかを使用してそれを行うことができます。テストしました。ただし、ファイルが配置されている現在のフォルダで実行する必要があります。
for file in *generic*.txt; do newname=$(echo $file | awk -F"-" '{print $3}' | sed 's/ _//g'); mv "$file" $newname;done
別のフォルダで実行するには、次のスクリプトを試してください。
#!/bin/bash
SRCFLDR=yoursourcefolder
for file in $SRCFLDR/*generic*.txt;do
newname=$(echo $file | awk -F"-" '{print $3}' | sed 's/ _//g')
mv "$file" $newname
echo $file has been renamed to $newname
done
答え3
この単純なスクリプトはトリックを実行する必要があります。
for f in *[0-9]*.*; do
base=${f%.*}
mv -- "$f" "${base//[^0-9]}.${f##*.}"
done