如何从管道的输出中回显子字符串?

如何从管道的输出中回显子字符串?

我发现这里如何在 bash 中提取子字符串,但我不知道如何在管道之后应用它。例如:

some func | echo ${string:12:5}

如何将 的输出分配some func给变量string

答案1

回答

如果您只想从 中提取输出some_func,则无需将其存储在变量中,只需将输出发送到cut该变量即可提取请求的字符:

some_func | cut -c 12-16  

解释

cutstdin将根据指定的选项 提取并提取请求的范围。

-c表示范围以字符指定。

12-16字符以 index 开头的范围1,而不是以0.
因此,这将采用位置12131415处的字符16

作为斯蒂芬·查泽拉斯我留下了疑问,请注意,这适用于每一行输入,而不仅仅是第一行。

答案2

${string:offset:length}是一个参数扩展运算符,可扩展到变量中的字符范围$string

为了得到一系列字节从输入中(这也适用于单字节字符),您可以使用:

func | tail -c +12 | head -c 5

获取从第 12 个字节开始的 5 个字节(从 1 开始的偏移量)。选项-c不是head标准的,但很常见。

func请注意,在输出第 16 个字节后,它可能会被杀死,因为head在输出这 5 个字节后将退出,并且tail如果它尝试在此之后写入更多数据,则会被杀死,这将波及到func.

您还可以这样做:

func | dd bs=1 skip=11 count=5 2> /dev/null

2> /dev/null是为了避免最后出现状态消息。但这会抑制所有错误。使用 GNU dd,您可以将其替换为status=none仅抑制状态。

对于较大的 值length,效率会较低,因为它一次读取一个字节。再次使用 GNU dd,您可以通过执行以下操作来避免这种情况:

func | dd iflag=count_bytes,skip_bytes,fullblock skip=11 bs=64k count=5M status=none

每次读取最多 64KiB,以获得 5MiB 字节的数据。

现在,对于那些用字符(单字节或多字节)而不是字节来表示的偏移量和长度,这变得更加复杂。

一个选项是将整个输出存储在变量中并使用${var:offset:length}运算符正如其他人所表明的。但这意味着将整个输出存储在内存中。使用var=$(func)还意味着尾随换行符将被丢弃。

另一种选择是使用bash'sread -N读取给定数量的人物:

func | {
  IFS= read -rN 11 discarded
  IFS= read -rN 5 data
  printf '%s\n' "$data"
}

或者使用perl(对于大数据来说效率稍高):

func | perl -Mopen=locale -sne '
  BEGIN{$total = $o + $n; $/ = \$total}
  print substr($_, $o); exit' -- -o=10000 -n=5000000

答案3

string="$(func)"
echo "${string:12:5}"

相关内容