私がどうする適切に逆順で繰り返しますか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
。
私の警告:tail
nullで終わる文字列をうまく処理できないことを読みました。。これはMac OS Xではうまく機能しますが、すべての* nixについて保証することはできません。気をつけて進めてください。
私も言及しなければならないGNUパラレルxargs
代わりによく使用されます。確認してみることもできます。
私が何かを逃したようだから、他の人も参加しなければならない。