Deepin(Debianベース)システムには、次のビデオファイルを含むディレクトリがあります。
SL Benfica - Match 1 vs FC Porto.mp4
SL Benfica - Match 2 vs FC Porto.mp4
...
SL Benfica - Match 20 vs FC Porto.mp4
...
SL Benfica - Match 100 vs FC Porto.mp4
SL Benfica - Match 101 vs FC Porto.mp4
途中の数字の前にゼロを追加して、次のように並べ替えたいと思います。
SL Benfica - Match 001 vs FC Porto.mp4
SL Benfica - Match 002 vs FC Porto.mp4
...
SL Benfica - Match 020 vs FC Porto.mp4
...
SL Benfica - Match 100 vs FC Porto.mp4
SL Benfica - Match 101 vs FC Porto.mp4
モードに依存しない一般的なコマンドを探しています。 5と20のような数字を検索して、ファイル名の任意の場所やファイル名の終わりまたは先頭から005と020に変更します。
答え1
利用可能ですperl-rename
(Debianベースのシステムにインストールできる必要がありますsudo apt install rename
)。次のファイルを入力として使用します。
$ ls -1
'anotherFile.m4a'
'file 1 with 12 many 100 numbers 3.mp4'
'SL Benfica - Match 101 vs FC Porto.mp4'
'SL Benfica - Match 20 vs FC Porto.mp4'
'SL Benfica - Match 2 vs FC Porto.mp4'
以下を実行できます。
rename 's/(\d+)(?=.*\.)/sprintf("%03d",$1)/eg' *
これにより、名前が次のように変更されます。
'anotherFile.m4a'
'file 001 with 012 many 100 numbers 003.mp4'
'SL Benfica - Match 002 vs FC Porto.mp4'
'SL Benfica - Match 020 vs FC Porto.mp4'
'SL Benfica - Match 101 vs FC Porto.mp4'
どのよう100
に変更されずに残りがいっぱいになるかを確認してください。また、4の.m4a
合計はmp4
影響を受けません。
重要-n
:ファイル名が実際に変更される前に何が起こるかを確認するには、まずコマンドを実行します。
rename -n 's/(\d+)(?=.*\.)/sprintf("%03d",$1)/eg' *
\d+
1つ.
以上の数字()の前に1つ以上の数字()を見つける正規表現?=.*\.
。これは、内線番号の番号が変更されるのを防ぐためです。ただし、ファイル名に拡張子がない場合は機能しません。このようなファイルがある場合は、以下を使用してすべての数字を入力してください。
rename 's/(\d+)/sprintf("%03d",$1)/eg' *
は代替演算子で、でs/old/new/
置き換えられます。ここでは括弧内にあるので、一致するものは何でもあります。old
new
(\d+)
キャプチャされます$1
これにより、交換品の右側で使用できます。したがって、数字をゼロで埋められた数字で置き換えます(ゼロで埋められた数字は、長さが3になるまでsprintf("%03d", $number)
印刷されます)。$number
最後に、このフラグをe
使用すると、式(ここでsprintf
)を使用g
して代替項目をグローバルに作成して、入力行(ファイル名)のすべての一致に適用できます。
番号に3つ以上のゼロが追加されている場合は、3-0パディングに切り捨てられます。だからfile 00000001.mp3
それはなりますfile 001.mp3
。
答え2
そしてzsh
:
autoload -Uz zmv # best in ~/.zshrc
zmv -n '(*).mp4' '${1//(#m)<->/${(l[3][0])MATCH}}.mp4'
満足すれば削除-n
(テスト実行)します。
zmv
zsh glob パターンに従ってファイル名を変更します。これ(*).mp4
はで終わるファイル名と一致し、.mp4
前の部分.mp4
は次のとおりです。キャプチャされますだから$1
代用として使えます。${1//pattern/replacement}
:ksh演算子は、引数(ここで$1
)を拡張すると置換を実行します。- これはzshモード
pattern
です。置換など、一致するテキストを使用できるようにすることは、数値一致演算子の最も単純な形式で、1つ以上の10進数シーケンスと一致します。と同じです。(#m)<->
extendedglob
(#m)
$MATCH
<->
<x-y>
[0-9]##
${(l[3][0])param}
引数拡張フラグを使用して、l[length][padstring]
ゼロから長さ3までの拡張を左に塗りつぶします$MATCH
(数字も長さ3に切り捨てます)。
少し複雑になりますが、切り捨てを防ぐことが可能です。
zmv -n '(*).mp4' '${1//(#m)<->/${(l[$#MATCH > 3 ? $#MATCH : 3][0])MATCH}}.mp4'
パディング+長さを3に切り捨てるのではなく、最大3の長さとパディングする文字列の長さまでパディング+切り捨てます。または、max()
自動ロード可能な関数で数学関数を使用することもできますzmathfunc
。
autoload -Uz zmv zmathfunc; zmathfunc
zmv -n '(*).mp4' '${1//(#m)<->/${(l[max(3, $#MATCH)][0])MATCH}}.mp4'
答え3
GNU sedを使用すると、次のことができます(拡張なしでも):
sed -E \
-e 'h;s/(.*)(\.[^.]*$)/\2/;ta;z;:a;x;s//\1/' \
-e 's/([0-9]{1,})/\n000\1\n/g' \
-e 's/\n[0-9]*([0-9]{3})\n/\1/g' \
-e 'G;s/\n//g' file
ループはなく、正規表現のみが使用されます。
最初の正規表現は一致します
'h;s/(.*)(\.[^.]*$)/\2/;ta;z;:a;x;s//\1/'
拡張をスケジュールされたスペース(存在する場合)に配置します。残りはパターン空間に残してください。's/([0-9]{1,})/\n000\1\n/g'
各数値ストリームを別々の行に配置し、その前に3つのゼロを追加します。
前にゼロがあり、独自の行になるように変更する各番号を展開してから、次の操作を行います。
's/\n[0-9]*([0-9]{3})\n/\1/g'
各数値行から最後の3桁を抽出します。'G;s/\n//'
起動時にキャプチャされた拡張機能を再接続します。
ソースリストが次の場合:
➤ cat file
1- 23.m2
ATestFile.mp4
SomeFile.m4a
AFileWithNumbers23inside.mp4
File 1 with 12 some 100 numbers 3.mp4
SL Benfica - Match 1 vs FC Porto.mp4
SL Benfica - Match 2 vs FC Porto.mp4
SL Benfica - Match 20 vs FC Porto.mp4
SL Benfica - Match 101 vs FC Porto.mp4
結果は次のとおりです。
001- 023.m2
ATestFile.mp4
SomeFile.m4a
AFileWithNumbers023inside.mp4
File 001 with 012 some 100 numbers 003.mp4
SL Benfica - Match 001 vs FC Porto.mp4
SL Benfica - Match 002 vs FC Porto.mp4
SL Benfica - Match 020 vs FC Porto.mp4
SL Benfica - Match 101 vs FC Porto.mp4
したがって、ファイル名を変更するには(ファイル名に改行文字を含めないでください。拡張子の後にドットを付ける必要があります):
#!/bin/bash
for old in *; do
new=$( printf '%s\n' "$old" |
sed -E \
-e 'h;s/(.*)(\.[^.]*$)/\2/;ta;z;:a;x;s//\1/' \
-e 's/([0-9]{1,})/\n000\1\n/g' \
-e 's/\n[0-9]*([0-9]{3})\n/\1/g' \
-e 'G;s/\n//'
);
if [[ ! -f $new ]]; then
echo \
mv "$old" "$new";
fi
done
スクリプトが満足のいくものであれば、削除してecho
実際にファイルを変更してください。
答え4
この試み
$ ls SL*mp4 | awk -v mvCmd='mv "%s" "%s"\n' '{ old=$0; $5=sprintf("%3.3d",$5); printf mvCmd,old,$0 }'
新しいファイル名が正しい場合は、コマンドを再実行して出力をbashなどのシェルにパイプします。
このコマンドは元のファイル名(以前)を保存し、5番目の列($ 5)をprintfの列の1つ(3つの数字、小数点なし、0で始まる)に変更し、古い名前と新しい名前の周りの引用符を使用します。 mvを印刷します(置き換えられた命名)。 )コマンド。
awkにはデフォルトでファイル名変更コマンドがないため、出力をbashにパイプする必要があります。