人们经常使用cut甚至awk只是通过模式或使用分隔符减去字符串的一部分。
另外,许多人使用$ {VARIABLE:start_position:length}进行子字符串bash操作,这非常快。
但是bash提供了一种使用#,##,%和%%来处理文本字符串的强大方法-它称为bash变量扩展。
使用此语法,您可以在无需执行外部命令的情况下减少模式的需要,因此它将非常快速地工作。
下面的示例显示了如何使用cut或变量扩展从字符串中获取第三列(shell),其中用冒号«username:homedir:shell»分隔的值(我们使用*: mask和##命令,这意味着:将所有字符向左剪切,直到找到最后一个冒号为止):
$ STRING="username:homedir:shell"
$ echo "$STRING"|cut -d ":" -f 3
shell
$ echo "${STRING##*:}"
shell
第二个选项不启动子进程(cut),并且根本不使用管道,这样可以更快地工作。而且,如果您在管道几乎不移动的Windows上使用bash子系统,则速度差异会很大。
让我们看一下Ubuntu上的示例:循环执行我们的命令1000次
$ cat test.sh
#!/usr/bin/env bash
STRING="Name:Date:Shell"
echo "using cut"
time for A in {1..1000}
do
cut -d ":" -f 3 > /dev/null <<<"$STRING"
done
echo "using ##"
time for A in {1..1000}
do
echo "${STRING##*:}" > /dev/null
done
结果
$ ./test.sh
using cut
real 0m0.950s
user 0m0.012s
sys 0m0.232s
using ##
real 0m0.011s
user 0m0.008s
sys 0m0.004s
差别是几十倍!
当然,上面的例子太人为了。在实际示例中,我们将不使用静态字符串,而是要读取真实文件。对于“ cut ”命令,我们只将/etc /passwd重定向到它。在##的情况下,我们必须创建一个循环并使用内部的' read '命令读取文件。那么谁将赢得这场案子呢?