forループをどのように反転しますか?

forループをどのように反転しますか?

私がどうする適切に逆順で繰り返しますかfor

for f in /var/logs/foo*.log; do
    bar "$f"
done

ファイル名の奇妙な文字を損なわない解決策が必要です。

答え1

Bashまたはkshでは、ファイル名を配列に入れ、逆の順序で配列を繰り返します。

files=(/var/logs/foo*.log)
for ((i=${#files[@]}-1; i>=0; i--)); do
  bar "${files[$i]}"
done

このオプションを設定すると、上記のコードはzsh ksh_arrays(kshエミュレーションモード)でも実行されます。 zshには、glob修飾子を介して一致順序を変更するより簡単な方法があります。

for f in /var/logs/foo*.log(On); do bar $f; done

POSIXには配列が含まれていないため、移植性が必要な場合は、文字列配列を直接格納する唯一のオプションは位置引数です。

set -- /var/logs/foo*.log
i=$#
while [ $i -gt 0 ]; do
  eval "f=\${$i}"
  bar "$f"
  i=$((i-1))
done

答え2

改行文字が「流行文字」だと思わない限り、次のことを試してください。

ls /var/logs/foo*.log | tac | while read f; do
    bar "$f"
done

答え3

スペースで区切られた文字列のリストを逆順に繰り返す方法を知りたい人がいる場合は、次のようにします。

reverse() {
  tac <(echo "$@" | tr ' ' '\n') | tr '\n' ' '
}

list="a bb ccc"

for i in `reverse $list`; do
  echo "$i"
done
> ccc
> bb 
> a

答え4

find /var/logs/ -name 'foo*.log' -print0 | tail -r | xargs -0 bar

必要な方法で動作する必要があります(これはMac OS Xでテストされており、以下に警告があります...)。

見つかったマニュアルページから:

-print0
         This primary always evaluates to true.  It prints the pathname of the current file to standard output, followed by an ASCII NUL character (charac-
         ter code 0).

デフォルトでは、文字列 + glob と一致するファイルを探し、各ファイルを NUL 文字で終了します。ファイル名に改行やその他の奇妙な文字が含まれている場合、findはそれをうまく処理する必要があります。

tail -r

パイプを介して標準入力を取得し、それを逆にします(tail -r印刷に注意してください)。みんな標準デフォルトの最後の10行だけでなく、stdoutに入力します。man tailより多くの情報を知りたい場合)。

次にパイプで接続しますxargs -0

-0      Change xargs to expect NUL (``\0'') characters as separators, instead of spaces and newlines.  This is expected to be used in concert with the
         -print0 function in find(1).

ここで xargs は、 fromfindと reverse から渡される NUL 文字で区切られた引数を見ると予想しますtail

私の警告:tailnullで終わる文字列をうまく処理できないことを読みました。。これはMac OS Xではうまく機能しますが、すべての* nixについて保証することはできません。気をつけて進めてください。

私も言及しなければならないGNUパラレルxargs代わりによく使用されます。確認してみることもできます。

私が何かを逃したようだから、他の人も参加しなければならない。

関連情報