2
cat list.txt | grep '^http://.*\.osm\..*$' | while read line; do
    fn=$(basename $line)
    do_something()
done
# TODO: check if it did something

grep コマンドが何も返さない場合、ループには入らず、do_something()は実行されません。

while ループの外で $fn の内容を確認できません。 Bash variable scopeを参照してください。

ここでdo_something()が実行されたかどうかを確認するための最も侵襲性の低いソリューションは何ですか?

4

5 に答える 5

3

flagループが実行されると値が変更されるa を使用できます。以下はポックです。

shopt -s lastpipe   # bash 4.2 or greater only
flag="false"
cat list.txt | grep '^http://.*\.osm\..*$' | while read line; do
    fn=$(basename $line)
    do_something()
    flag="true"
done

if [ "$flag" = "true" ]
then
    echo "loop was executed"
fi

whilea にまたがる場合は、次を使用する必要がありますsub-shell(以下にコメントしたすべての人に感謝します)。

 while read line
   do
       fn=$(basename $line)
       do_something()
       flag="true"
   done < <(grep '^http://.*\.osm\..*$' list.txt)
于 2013-05-14T16:06:07.933 に答える
2

パイプラインの代わりにプロセス置換を使用できます。これにより、フラグを便利に設定できます。

flag=0
while read line; do
    flag=1
    fn=$(basename $line)
    do_something()
done < <( grep '^http://.*\.osm\..*$' list.txt )

if [[ $flag == 1 ]]; then
   ...
fi
于 2013-05-14T16:21:18.043 に答える
2

grepの出力を変数に保存し、明示的にテストします。

filtered=$(cat list.txt | grep ....)

if [ -z "$filtered" ] ;
  ... handle empty output ..
 else
  ... do your while loop here... 
fi

ところで: 改行は 内に保持され"$filtered"ますが、使用するときは必ず引用してください。

于 2013-05-14T16:16:45.737 に答える
1

@chepner ソリューションのバリエーション:

flag=0
while read line; do
    grep -q '^http://.*\.osm\..*$' <<< $line && {
      flag=1
      fn=$(basename $line)
      do_something()
    }
done < list.text

if [[ $flag == 1 ]]; then
   ...
fi

次に、ニーズに適したものを使用してください。

于 2013-05-14T16:31:37.220 に答える