1

私は過去数週間に多くの時間を費やし、ここに投稿しました。私はついにbashの学習にかなり近づいたと思いますが、コードに1つの問題があり、それが実行されない理由を一生理解できません。ターミナルで各行を実行すると結果が返されますが、何らかの理由で実行するように指定すると、何も実行されません。構文エラーが発生します:予期しない単語(「do」を期待)。

#!/bin/bash

image="/Home/Desktop/epubs/images"

for f in $(ls "$image"*.jpg); do
    fsize=$(stat --printf= '%s' "$f");
    if [ "$fsize" -eq "40318" ]; then
       echo "$(basename $f)" >> results.txt
    fi
done

私は何が欠けていますか?

4

3 に答える 3

1

問題は行末にある可能性があります。スクリプトファイルに、WindowsではなくUNIXの行末があることを確認してください。

また、の出力を繰り返し処理しないでくださいls。シェルでグロブを使用します。

for f in "$file"/*.jpg ; do
于 2012-09-20T20:12:56.810 に答える
0

これが私がそれをする方法です。

#!/bin/bash -e

image="/Home/Desktop/epubs/images"

(cd "$image" 
 for f in *.jpg; do
   let fsize=$(stat -c %s "$f")
   if (( fsize == 40318 )); then
     echo "$f"
   fi
 done) >results.txt

これ-eは、何か問題が発生した場合(たとえば、ディレクトリにcdできない場合)にスクリプトが終了することを意味します。その動作に満足しているときに、多くのエラーチェックを節約できます。

括弧は、cdコマンドがサブシェル内にあることを意味します。周囲のスクリプト(へのリダイレクトを含むresults.txt)は、開始したディレクトリにまだあります。

*.jpgこれでディレクトリに移動したので、ディレクトリプレフィックスなしで検索できbasename、何も呼び出す必要はありません。

サイズ値を文字列ではなく数値として使用letおよび処理するため、値のフォーマットを選択する(( == ))際の不自然さにつまずくことはありません。stat

毎回追加するのではなく、ループ全体の出力を結果ファイルにリダイレクトするだけです。より効率的です。results.txt保持したい既存のコンテンツがある場合は、>元に戻すだけで済みますが>>、ループ全体に残しておく方が、ファイルを開いて反復ごとに追加するよりも効率的です。

于 2012-09-20T20:10:30.120 に答える
0

forループには、反復する値のリストがないようです。

image="/Home/Desktop/epubs/images"
for f in $(ls "$image"*.jpg); do

$image/で終わらないため、lsコマンドは次のように展開されます

for f in $(ls /Home/Desktop/epubs/images*.jpg); do

おそらく結果として

for f in ; do

構文エラーが発生します。最も簡単な修正は

for f in $(ls "$image"/*.jpg); do

しかし、あなたは他の答えのアドバイスを受けてスキップするべきですls

for f in "$image"/*.jpg; do
于 2012-09-20T20:17:26.083 に答える