1

端末で「ls -lrt」を実行すると、次のような大きなリストが表示されます。

-rw-r--r--  1 pratik  staff   1849089 Jun 23 12:24 cam13-vid.webm
-rw-r--r--  1 pratik  staff   1850653 Jun 23 12:24 cam12-vid.webm
-rw-r--r--  1 pratik  staff   1839110 Jun 23 12:24 cam11-vid.webm
-rw-r--r--  1 pratik  staff   1848520 Jun 23 12:24 cam10-vid.webm
-rw-r--r--  1 pratik  staff   1839122 Jun 23 12:24 cam1-vid.webm

サンプルとして上記の一部のみを示しました。

すべてのファイルの名前を現在よりも 1 つ小さい名前に変更したいと思います。

例えば、

mv cam1-vid.webm cam0-vid.webm
mv cam2-vid.webm cam1-vid.webm
.....
....
mv cam 200-vid.webm cam199-vid.webm

os x / linux bash スクリプト (おそらく sed を使用) を使用してこれを行うにはどうすればよいですか?

4

3 に答える 3

1

を使用findし、ファイル名を分割して、番号を見つけ、1 を引いて、名前を変更します。

find . -name "cam*-vid.webm" -print0 | while read -d\$0 old_name
do
    number=${old_name#cam}        #Filter left to remove 'cam' prefix
    number=${number%-vid.webm"}   #Filter right to remove '-vid.webm' suffix
    $((number -= 1))
    new_name="cam${number}-vid.webm"
    echo "mv \"$old_name\" \"$new_name\""
done | tee results

これは単にコマンドを出力するだけです(それが私が持っている理由ですecho)。という名前のファイルにパイプしていますresults。このコマンドが完了したら、必要なresultsすべてのことを行っていることを確認してください。このような操作があるときはいつでも、厄介な驚きがある可能性があります. たとえば、名前を変更cam02-vid.webmするcam01-vid.webm前に名前を変更するcam01-vid.webmと、上書きされますcam01-vid-webm

おそらく、より安全な方法は、必要なファイル番号を明示的に指定することです。

for number in {1..200}
do
    $((old_number = $number + 1))
    echo mv "\"cam${old_number}-vid.webm\" \"cam${number}-vid.webm\""
done | tee results

役立つヒント:resultファイルに問題がなければ、実際にシェル スクリプトとして実行できます。

 $ bash results

もう 1 つの可能性は、古いファイルが存在することを確認するためにテストすることです。

for number in {1..200}
do
    $((old_number = $number + 1))
    if [ -f "$cam${old_number}-vid.webm" ]
    then
        echo mv "\"cam${old_number}-vid.webm\" \"cam${number}-vid.webm\""
    else
        echo "ERROR: Can't find a file called 'cam${old_number}-vid.webm'"
    fi
done | tee results
于 2013-07-23T22:11:24.477 に答える
0

パール

最初に、すべての入力ファイルをトラバースし( )、@ARGVリンクではなくプレーン ファイルをフィルター処理し ( grep)、番号を抽出し( )、map上書きを避けるために昇順で数値的に並べ替えます ( sort)。後で、番号を減らして元のファイルの名前を変更する新しいファイルを作成します。

perl -e '
    for ( 
        sort { $a->[0] <=> $b->[0] } 
        map { m/(\d+)/; [$1, $_ ] } 
        grep { -f $_ && ! -l $_ } 
        @ARGV 
    ) {
        $n = --$_-> [0];

        ($newname = $_->[1]) =~ s/\A(?i)(cam)\d+(.*)\z/$1$n$2/;
        print "Executing command ===> rename $_->[1], $newname\n";
        rename $_->[1], $newname;
}' * 

ディレクトリの初期コンテンツを次のように仮定します。

cam1-vid.webm
cam13-vid.webm
cam12-vid.webm
cam11-vid.webm
cam10-vid.webm
cam2-vid.webm

コマンドを実行すると、次の結果が得られます。

cam0-vid.webm
cam10-vid.webm
cam11-vid.webm
cam12-vid.webm
cam1-vid.webm
cam9-vid.webm
于 2013-07-23T20:43:15.400 に答える