長い一連の-execコマンドを実行しており、実行の開始時にタイムスタンプを抽出して後続のコマンドの値として使用しようとしています。可能ですか?それは次のとおりです。
find . -exec NOW=$(date +%s) {} \; -exec echo $NOW."$0" {} \;
find . -exec set NOW=$(date +%s) {} \; -exec echo $NOW."$0" {} \;
find . -exec export NOW=$(date +%s) {} \; -exec echo $NOW."$0" {} \;
これはうまくいきませんが、値を設定する代わりに$(date + % s)を使用すると、後続の各-execが時間とともに発生するため、タイムスタンプが一貫しなくなります。
私が望むのは、ファイルごとに異なるタイムスタンプを持つことです。たとえば、誰かの提案を変更すると、私の意図をよりよく表現することができます。
find . -exec sh -c '
NOW=$(date +%s); for f in "$@"; do echo "$NOW $f First Output"; sleep 3; echo "$NOW $f Second Output"; done
' find-sh {} +
このコマンドは私が望むことはしませんが、最初のファイルに対して操作を実行するのに遅れてタイムスタンプを変更しないでください。タイムスタンプとファイル名、スリープ3を出力し、ファイルに対して同じタイムスタンプを出力する必要があることを示します。次に、次のファイルに使用する新しいタイムスタンプを作成したいと思います。
答え1
-exec
次のように1つだけ使用してくださいsh -c
。
find . -exec sh -c '
NOW=$(date +%s);
echo "$NOW $1 First Output";
sleep 3;
echo "$NOW $1 Second Output";
' find-sh {} \;
あるいは、何らかの理由で接続されたsに固執するために一時ファイルを使用できますが、その一時ファイルを読むたびに次のものが-exec
必要です。sh -c
find . \
-exec sh -c 'date +%s > /tmp/now' \; \
-exec sh -c 'echo "$(cat /tmp/now) $1 First Output"' find-sh {} \; \
-exec sleep 3 \; \
-exec sh -c 'echo "$(cat /tmp/now) $1 Second Output"' find-sh {} \;
-exec
シェルが実行する$(..)
前にその部分を評価するため、以下は機能しませんfind
。
-exec echo "$(cat /tmp/now) {} First Output" \;
添付:
あなたはこれがどこから来たfind-sh
のか尋ねることができます-exec sh -c '...' find-sh {}
。これが答えです。
答え2
NOW
各ファイルにリセットします。つまり、~へサイクルfor
:
find . -exec sh -c '
for f do
NOW=$(date +%s)
echo "$NOW $f First Output"
sleep 3
echo "$NOW $f Second Output"
done
' find-sh {} +
答え3
何をしたいのかわかりませんが、$NOW
各ファイルの処理中に各ファイルの値を現在の時代に更新したい場合は、その変数zsh
($EPOCHSECONDS
または$EPOCHREALTIME
ナノ秒を望む場合)モジュールを使用できますzsh/datetime
(または${(%):-%D{%s}}
バンドを使用しない)zsh/datetime
。あまり明確ではない):
find . -exec zsh -c '
zmodload zsh/datetime
typeset -F SECONDS # make it float
for file do
start_time=$EPOCHSECONDS SECONDS=0
print -r $start_time processing $file
processing $file
end_time=$EPOCHSECONDS duration=$SECONDS
print start=$start_time end=$end_time duration=$SECONDS
done' zsh {} +
またはzsh
can dofind
の作業は再帰的グローブを使うことだからです。
#! /bin/zsh -
zmodload zsh/datetime
typeset -F SECONDS # make it float.
for file (./**/*(ND)) {
start_time=$EPOCHSECONDS SECONDS=0
print -r $start_time processing $file
processing $file
end_time=$EPOCHSECONDS duration=$SECONDS
print start=$start_time end=$end_time duration=$SECONDS
}
bash
シェルではstart_time=$EPOCHSECONDS
withと同等のものが得られますprintf -v start_time '%(%s)T'
。