1

私はこの質問がされたことを知っていますが、私は複数の解決策を見つけることができず、それは私にとってはうまくいきません。基本的に、私は次のようなファイルリストを取得するbashスクリプトを探しています。

image1.jpg
image2.jpg
image3.jpg

次に、それぞれのコピーを作成しますが、順番に逆方向に番号を付けます。したがって、シーケンスには次の3つの新しいファイルが作成されます。

image4.jpg
image5.jpg
image6.jpg

それでも、image4.jpgはimage3.jpgの手付かずのコピーであり、image5.jpgはimage2.jpgの手付かずのコピーであるというようになります。私はすでにこのスタックオーバーフローの質問で概説されている解決策を試しましたが、運がありませんでした。私は確かにbashスクリプトのパスをそれほど遠くはありません。最初にリストされた回答のコードのチャンクを取得してスクリプトを作成すると、常に「2:構文エラー:」(「予期しない」が何度も繰り返されます。構文を(少しだけ変更しようとしましたが、成功しませんでした。したがって、私が何か間違ったことをしているのか、より良いスクリプトがあります。

以前にこれを投稿しなかったことをお詫びしますが、私が使用しているコードは次のとおりです。

image=( image*.jpg )  
MAX=${#image[*]}  
for i in ${image[*]}  
do  
   num=${i:5:3} # grab the digits  
   compliment=$(printf '%03d' $(echo $MAX-$num | bc))  
   ln $i copy_of_image$compliment.jpg  
done

そして、このコードを取得してnanoを含むファイルに貼り付け、最初の行として!#/ bin / bashを追加してから、chmod +x scriptを介してbashで実行しsh scriptます。もちろん、私のテスト実行では、適切にimage1.jpgというタイトルのファイルを使用していますが、このスクリプトを、必ずしもimage(integer).jpgというタイトルではないjpegのディレクトリに適用する方法についても考えていました。構造を維持しながら、これらのほとんどは1つの単語、数字、.jpgの順であり、使用するたびにスクリプトを書き直す必要がないのは便利です。

4

2 に答える 2

0

おそらくこのようなものです。script image*.jpgワイルドカードが、同じ長さの単調に増加する数を持つ通常のパターンに一致するファイルのセットに一致する場合や、現在のディレクトリ内のファイルのあまり規則的でないサブセットでは理想的ではありません。単純に、最後のファイルの数字インデックスにファイル名の総数に 1 を加えた値が、ループする数字の範囲であると想定しています。

#!/bin/sh

# Extract number from final file name
eval lastidx=\$$#
tmp=${lastidx#*[!0-9][0-9]}
lastidx=${lastidx#${lastidx%[0-9]$tmp}}
tmp=${lastidx%[0-9][!0-9]*}
lastidx=${lastidx%${lastidx#$tmp[0-9]}}

num=$(expr $lastidx + $#)
width=${#lastidx}

for f; do
    pref=${f%%[0-9]*}
    suff=${f##*[0-9]}
    # Maybe show a warning if pref, suff, or width changed since the previous file
    printf "cp '$f' '$pref%0${width}i$suff'\\n" $num
    num=$(expr $num - 1)
done |
sh

これはsh互換性があります。前にあるexprものと部分文字列の抽出は醜いですが、ボーン互換です。Bash の組み込みの算術および文字列操作構造に問題がなければ、その形式への変換は簡単です。

(明確に言うと、 の値の末尾をトリミングして${var%foo}返し、値の先頭から同様のトリミングを行います。正規のシェル ワイルドカード マッチング演算子は、トリミング対象の式で使用できます。 の値の長さを返します。)$varfoo${var#foo}${#var}$var

于 2012-05-11T11:56:08.383 に答える
0
  • おそらく、実際のテスト データは 001 から 300 まで実行されますが、ここでは image1 2 3 があるため、ファイル名から 3 桁ではなく 1 桁を抽出します。数値=${i:5:1}

  • 整数演算は、bc を呼び出さずに bash で実行できます

  • ${#image[@]} は ${#image[*]} よりも堅牢ですが、ここでは違いはありません。
  • 辞書は引かなかったけど、彼女への褒め言葉じゃない?反対は補数ですね。:)
  • 他のコマンドはリンクを作成しました - コピーを作成するには、cp を呼び出します。

コード:

#!/bin/bash
image=( image*.jpg )
MAX=${#image[@]}
for i in ${image[@]}
do
    num=${i:5:1}
    complement=$((2*$MAX-$num+1))
    cp $i image$complement.jpg
done 

最も重要: bash の場合は、bash で呼び出します。ベスト:(あなたがしたように)シバンを実行し、実行可能にして ./name で呼び出します。sh 名で呼び出すと、間違ったインタープリターが強制されます。実行可能にしない場合は、bash 名と呼びます。

于 2012-05-11T08:53:09.210 に答える