让我们定义一个例子var:
$ var='The quick brown fox jumped over the lazy dog on the way to the market'
现在让我们使用 cut 选择字符 18 到 53:
$ echo $(cut -c 18-53 <<<"$var")
ox jumped over the lazy dog on the w
因为cut 期望从标准输入(如果不是文件)读取,我们使用<<< 告诉bash 在标准输入上提供$var 的内容。这被称为 这里的字符串。
或者,我们可以单独使用 bash 选择相同的字符:
$ echo ${var:17:36}
ox jumped over the lazy dog on the w
构造${var:17:36} 称为子字符串扩展。它从位置 17 开始选择 36 个字符。(在 bash 中,与 cut 不同,第一个字符编号为零。)
我们当然可以将选中的字符串赋值给一个变量:
$ token=${var:17:36}
$ echo "$token"
ox jumped over the lazy dog on the w
或者:
$ token=$(cut -c 18-53 <<<"$var")
$ echo "$token"
ox jumped over the lazy dog on the w
POSIX
以上命令在 bash 中工作。如果我们想要移植到 POSIX shell,那么我们既不能使用 子字符串扩展,也不能使用 here 字符串。相反,正如Gordon Davisson 指出的那样,我们可以使用:
$ echo "$var" | cut -c 18-53
ox jumped over the lazy dog on the w
或:
$ token=$(echo "$var" | cut -c 18-53)
$ echo "$token"
ox jumped over the lazy dog on the w
gniourf_gniourf 提出了另一种 POSIX 方法,这个方法避免了外部进程:
$ printf '%.36s\n' "${var#?????????????????}"
ox jumped over the lazy dog on the w
cut 和 bash 子串扩展的比较
正如David C. Rankin 在 cmets 中指出的那样,使用 bash 的内部字符串处理有很大的优势。一是使用 bash 的内部命令可以避免产生额外的子 shell 和可执行文件。如果在循环中生成额外的子shell,则会极大地影响性能。
此外,命令替换具有从其输出中删除尾随换行符的副作用。这可能会导致不必要的意外。使用 bash 的内部字符串处理可以避免这种副作用。