的输出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
您可以使用mapfile
和处理替换将exif
输出存储到数组中,然后访问最后一个元素
mapfile -t arr < <(
exif --debug --machine-readable --tag=DateTimeOriginal "$file" 2>&1)
printf '%s\n' "${arr[@]:(-1)}"
2013:08:22 18:01:16