将内置读取与管道和此处字符串一起使用

Using builtin read with pipeline and here strings

我正在处理一组图片,其中 "file" returns 以下内容:

$ file pic.jpg
pic.jpg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 96x96, segment length 16, baseline, precision 8, 231x288, frames 3
$ file pic.jpg | cut -d',' -f8 | tail -c+2
231x288

因此,在继续裁剪之前,我使用内置 "read" 选择两个变量的维度。

但有些事情让我不知所措。为什么这个构造不起作用...

$ ( file pic.jpg | cut -d',' -f8 | tail -c+2 | IFS=x read width height ; echo w:$width h:$height; )
w: h:

...当这个构造起作用时?

$ ( IFS=x read width height <<< $(file pic.jpg | cut -d',' -f8 | tail -c+2) ; echo w:$width h:$height; )
w:231 h:288

总而言之,为什么我不能在那种情况下使用内置 "read" 的管道?

在bash中,管道中的命令是运行在subshells中(参见手册中Pipelines的最后一段)。当 subshell 退出时,您在 subshell 中声明的任何变量都将消失。

您可以使用 { } 分组结构将 readecho 保持在同一个子shell:

file pic.jpg | cut -d',' -f8 | tail -c+2 | { IFS=x read width height ; echo w:$width h:$height; }

这就是 here-string 有用的原因:它 运行 是 current shell 中的 read 命令,所以变量在下一个命令中可用。

您可以使用 ImageMagick 中的 identify 并执行

$ identify -format 'w=%[w]; h=%[h]' file.jpg

请注意 =; 的用法,这样您就可以

$ eval $(identify -format 'w=%[w]; h=%[h]' file.jpg)

在 shell

中设置变量

实际上,当您使用 bash 时,有一种更简单的方法只需要一行,没有 evals,没有 cuts 也没有 [=15] =]s:

read w h < <(identify -format "%w %h" file.jpg)

当你想提取很多参数时,它真的很有用,比如高度、宽度、平均值、标准差、色彩空间和唯一颜色的数量等,一次调用就可以了:

read w h m s c u < <(identify -format "%w %h %[mean] %[standard-deviation] %[colorspace] %k" file.jpg)