出力は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