ksh의 역따옴표 안의 따옴표

ksh의 역따옴표 안의 따옴표

HP-UX Unix에서 다음 명령을 사용하여 파일의 현재 날짜를 얻으려고 합니다.

$ ls -lrt ABC.LOG* |grep "`date +"%b %d"`"

그러나 오류가 발생합니다.

ksh: : cannot execute
grep: can't open %d

어떤 제안이 있으십니까?

답변1

오류는 매개변수에 대한 참조 grep와 백틱이 잘 중첩되지 않는다는 사실에서 발생합니다.

grep "`date +"%b %d"`"

이것은 다음과 같이 쓰는 것이 더 좋습니다.

grep "`date +'%b %d'`"

...또는 더 나은,

grep "$(date +'%b %d')"

실제로 $(...)내부 큰따옴표는 유지할 수 있지만 역따옴표는 유지할 수 없습니다.

grep "$(date +"%b %d")"

grep 출력의 또 다른 옵션은 ls다음과 같습니다.

find . -type f -name "ABC.LOG*" -ctime -1

-type f현재 디렉토리에서 주어진 패턴 및 ctime( )과 일치하는 이름을 가진 모든 일반 파일을 찾습니다.현재 시간으로부터 24시간 이내. 파일의 ctime은 파일 데이터 또는 메타데이터가 마지막으로 수정된 시간입니다.

그러나 그것은 당신이 달성하고자 하는 것과 정확히 같지는 않습니다. 이는 하위 디렉터리에도 반복됩니다.

답변2

Bourne 쉘에서와 마찬가지로 Korn 쉘에서도 따옴표와 백틱(고대 명령 대체 형식)이 일치하지 않을 수 있으므로 토크나이저가 백틱이 끝나는 위치를 파악하도록 도와야 합니다. 백틱 내부에는 또 다른 수준의 백슬래시 처리가 있습니다.

echo "`date"

유효하며 다음과 같습니다.

echo "`date`"
echo "$(date)"

그리고:

echo `echo "foo`

유효하며 다음과 같습니다.

echo `echo "foo"`
echo $(echo "foo")

이렇게 하면:

grep "`date +"%b %d"`"

이것은 grep단어로 처리된 다음( "`date +"큰따옴표 안의 닫히지 않은 백틱)은 큰따옴표 안의 닫히지 않은 다른 백틱과 연결됩니다. 그처럼%b%d"`"

grep "$(date +)"%b %d"$()"

(어떤 이유를 제외하고, 쉘은 오류를 일으키 echo "``"거나 일으키지 않더라도 (마치 사용자가 작성한 것처럼 ) 빈 이름으로 명령을 실행하려고 시도합니다.echo "$()"echo "`"echo "$("")"

따라서 여기서는 파서를 돕기 위해 백슬래시를 사용해야 합니다.

grep "`date +\"%b %d\"`"

이러한 백슬래시는 실제로 제거됩니다. date +"%b %d"명령 대체의 서브쉘에 의해 평가 됩니다 .

여기에서는 ksh닫히지 않은 따옴표가 허용되므로 실제로 이 작업도 수행할 수 있습니다.

grep "`date +\"%b %d"

(제가 이것을 추천하는 것은 아닙니다).

이는 또한 다음과 같이 중첩된 백틱을 얻는 방법이기도 합니다.

echo "`echo \"\`echo \\\"a  b\\\"\`\"`"

이 구문을 사용하는 사람이 거의 없고 새로운 형식( $(...)80년대 초반에 도입됨)을 사용하는 좋은 예:ksh

echo "$(echo "$(echo "a  b")")"

ABC.LOG*이제 특정 질문에 대해 오늘 마지막으로 수정된 현재 디렉터리의 파일을 나열하려는 것 같습니다 . 이렇게 하려면 다음을 수행할 수 있습니다.

touch -t "$(date +%Y%m%d0000)" .start-of-day &&
  find . ! -name . -prune -name 'ABC.LOG.*' \
    -newer .start-of-day -type f -exec ls -lrtd {} + &&
  rm -f .start-of-day

답변3

이 명령은 결과를 수행 하고 전달하는 find대신 올바른 도구를 사용하여 작동하므로 주의하세요.lsgrepls결과를 구문 분석하지 않음.

find /path/to/ -type f -name "ABC.LOG*$(date +"%b %d")*"

위는 오늘 날짜를 구하는 것입니다파일 이름, 오늘 생성/수정된 파일을 찾고 있다면 find다음과 같이 사용할 수 있습니다(GNU 버전 find):

find /path/to -type f -name "ABC.LOG*" -newermt 00:00

또는 지난 24시간 이내:

find /path/to -type f -name "ABC.LOG*" -newermt yesterday

또는 다음과 같습니다:

find /path/to -type f -name "ABC.LOG*" -newermt "$(date +"%b %d")"

관련 정보