여러 줄 문자열의 마지막 줄 추출

여러 줄 문자열의 마지막 줄 추출

출력은 exif다음과 같습니다.

ExifMnoteCanon: Loading entry 0xcf27 ('(null)')...
ExifMnoteCanon: Loading entry 0x3ca8 ('(null)')...
ExifMnoteCanon: Loading entry 0xf88a ('(null)')...
2013:08:22 18:01:16

내 bash 스크립트에서는 이것을 변수에 저장합니다.

datetime="$(exif --debug --machine-readable --tag=DateTimeOriginal "$file" 2>&1)"

bash 매개변수 대체를 사용하여 마지막 줄을 추출하고 싶습니다. 나는 이것이 효과가 있을 것이라고 생각합니다:

datetime="${datetime##*\n}"

그러나 출력은 다음과 같습니다.

ull)')...
2013:08:22 18:01:16

이것이 작동하지 않는 이유와 해결 방법은 무엇입니까?

답변1

ANSI C 스타일 이스케이프 시퀀스를 사용하여 줄 $'\n'바꿈을 나타냅니다.

% echo "$datetime"       
ExifMnoteCanon: Loading entry 0xcf27 ('(null)')...
ExifMnoteCanon: Loading entry 0x3ca8 ('(null)')...
ExifMnoteCanon: Loading entry 0xf88a ('(null)')...
2013:08:22 18:01:16

% echo "${datetime##*\n}"
ull)')...
2013:08:22 18:01:16

% echo "${datetime##*$'\n'}"
2013:08:22 18:01:16

보시다시피, 그렇지 않으면 \n문자 그대로 받아들여질 것입니다 n.

답변2

$''이제는 휴대성이 매우 좋아 졌지만sh(예를 들어 BSD는 if를 지원하지만 다운스트림 분기 는 지원 dash하지 않습니다.), POSIXLY:

eval 'printf "%s\n" "${datetime##*"'"$(printf '\n"')}\""

...성가시더라도 작동할 것입니다. 그러나 나는 일반적으로 변수에 개행 문자를 유지합니다 $nl.

printf "%s\n" "${datetime##*$nl}"

...관리가 더 쉬워졌습니다. 물론 다음과 같이 할 수 있습니다.

printf "%s\n" "${datetime##*"
"}"

...하지만 어쩌면 좀 웃겨 보일 수도 있어요.

답변3

또는 최신 버전에서는 치환을 사용하여 출력을 배열에 저장 하고 마지막 요소에 액세스 bash할 수 있습니다 .mapfileexif

mapfile -t arr < <(
         exif --debug --machine-readable --tag=DateTimeOriginal "$file" 2>&1)
printf '%s\n' "${arr[@]:(-1)}"
2013:08:22 18:01:16

관련 정보