运行 find 命令时如何设置值?

运行 find 命令时如何设置值?

我正在运行一长串 -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 {} +

该命令没有执行我想要的操作,但显示对第一个文件执行操作时的延迟不应更改时间戳,应输出时间戳和文件名,sleep 3,并输出该文件的相同时间戳。然后我希望它创建一个新的时间戳以与下一个文件一起使用。

答案1

-exec仅与 一起使用一个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不起作用,因为 shell 会在运行$(..)之前评估该部分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 {} +

或者因为zshcan dofind的工作是用它的递归 glob:

#! /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
}

bashshell 中,您可以获得start_time=$EPOCHSECONDS与 with等效的内容printf -v start_time '%(%s)T'

相关内容