Perl名前変更ツール(Debian)で算術を実行しようとしています


8

5つのmp3ファイルがあるとします。

01-trackfoo.mp3
02-trackbar.mp3
03-trackbaz.mp3
04-trackabc.mp3
05-trackxyz.mp3

これで、ファイルをすばやく聴くことができ(コンソールのmplayerでうまくいきます)、トラックの順序間違っていることがわかりました。05は実際には02で、残りは名前を変更する必要があります。したがって、最初に一時的な名前変更を行います。

01-trackfoo.mp3

02-trackbar.mp3
03-trackbaz.mp3
04-trackabc.mp3
00-trackxyz.mp3

ここで、「シフト」が必要です。02は03に、03は04に、04は05にすべきです。混乱を最小限に抑えるために、ex-05(現在は00)はmv後で編集されます。

私のアプローチはこれでした:(perl rename、Larry Wall、デフォルトはここDebian)

rename 's/0([2-4])([\s\S]+)/0($1+1)$2/' *

同様に(後で、さらにRTFMを実行した後)

rename 's/0([2-4])([\s\S]+)/0($1+1)$2/e' *

特に/e[val]修飾子評価以外のものを受け入れず、評価と文字列を組み合わせようとするとエラーがスローされるため、それらはどれも機能しませんでした。bash例えば、うまくそれを行うことができます foo$((1+6))に評価されますfoo7

では、これをどのように行うことができますか(これだけのためにスタンドアロンスクリプト全体を作成するつもりはなく、1行が望ましい)。

回答:


7

あなたはそれをほとんど持っていました。/e引用符とドット演算子を使用して、-modified置換内でリテラル文字列と文字列連結を明示的にする必要があるだけです。

rename 's/0([2-4])([\s\S]+)/"0".($1+1).$2/e' *

オリジナルの05はまだ名前が変更されていませんが、ワンライナーグリッチを解決するために+1されます。
Peter.O 2012

1
(マイナーノート、名前の変更が呼ばれprenameとディレクトリを開始するには名前が場合... Ubuntuの中を)$'\x01'2:このような予備的な名前の変更がprename 's/^05/\x012/' 05*...その後、上記の[2-4]名前の変更が...最終的なprename 's/^\x01/0/' $'\x01'2*トリックを行います。..それは行いません3 1を-liners ... 4番目の、およびで始まるファイルの存在の可能性の最初のチェックでは、$'\x01'このbashスニペットのようなものがそれをトラップします..shopt -s nullglob; x=($'\x01'*); [[ -n $x ]] && { echo '\x01' is not suitable; exit; }
Peter.O

やった!「伝える/ Eをものに触れないように:あなたのアランありがとう、私は人間が読める言葉で何をすべきかを知っていたものの、そのドット演算子は考えていなかった外の()」:)とbashのためのピーターのおかげで同様にアプローチします。その上、もし私がPHP構文がPerlの構文にどれほど近いかについて考えていたなら、おそらく試行錯誤によって解決策を見つけたでしょう。そのドットは、文字列連結のためのPHPにおけるJavaScriptの「+」に相当するためです。
Syntaxerror

4

このためだけにスタンドアロンスクリプト全体を作成するつもりはなく、ワンライナーが望ましい

事態が非常に複雑になっても、スクリプトを書かない理由は何もありません。実行ごとにこれを行う方法を覚えておくつもりはないので、毎回それを再発明するか、とにかくスクリプトでラップすることになります。

このような小さなことのために、私は一般的にBashでそれを解決しようとし始めます:

#!/bin/bash
if [ -z "$1" ] ; then echo Need arguments. ; exit 1 ; fi

typeset -i i=1
for f in "$*"
do
    tailbits=`echo "$f" | sed -e 's/^[0-9]+//'`
    mv "$f" sertmp-`printf %02d $i`"$tailbits"
    i=i+1
done

for f in "sertmp-*"
do
    mv "$f" `echo "$f" | sed -e s/^sertmp-//` 
done

基本的に、このスクリプトは先頭の数字をすべて取り除き、スクリプトに渡す順序に従ってファイルに番号を付けて、先頭にゼロが埋め込まれた増加するシリアル番号を配置します。

これは2つの段階で行われ、sertmp-名前の衝突のリスクを回避するために最初のパスにプレフィックスが付けられます。このスクリプトmp3-renamerを呼び出して、次のように呼び出すと、

$ mp3-renamer 01-foo.mp3 03-bar.mp3 04-qux.mp3

名前変更を行うために2つのパスを使用しない場合、最初の名前変更で些細な衝突が発生します。(01-foo.mp3-> 01-foo.mp3。)

ただし、次のように呼び出すと、

$ mp3-renamer 02-foo.mp3 01-foo.mp3

01-foo.mp31パスの名前変更を使用して、最初の名前変更で誤って消去してしまった。

問題がさらに複雑になった場合は、Perlで書き直します。その時点で、ハッシュを使用して古い名前から新しい名前へのマッピングを保持し、少し巧妙なコードを使用して適切な順序で名前を変更し、2パスの必要性を回避できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.