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쉘이 실행하기 $(..)전에 해당 부분을 평가하기 때문에 다음은 작동하지 않습니다 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}}band 사용하지 않음 ) 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 do find의 작업은 재귀적 글로브를 사용하는 것이기 때문입니다.

#! /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=$EPOCHSECONDSwith 와 동등한 것을 얻을 수 있습니다 printf -v start_time '%(%s)T'.

관련 정보