bash - 在字符串上运行 sed,使用 "echo"+ "pipe"优于 "<<<"的好处

标签 bash sed io

<分区>

通常我看到人们使用 sed 操作字符串,如下所示:

echo "./asdf" | sed -n -e "s%./%%p"

我最近了解到我还可以:

sed -n -e "s%./%%p" <<< "./asdf"

是否有理由避免后者? 例如,它是特定于 bash 的行为吗?

最佳答案

我应该如何修剪./从路径的开头开始(或执行其他简单的字符串操作)?

Bash 的内置语法称为 parameter expansion . ${s#./}将展开$s与任何前导 ./在 shell 内部修剪,没有子进程或其他开销。 BashFAQ #100涵盖许多额外的字符串操作操作。


echo "$s" | ...之间有什么区别?和 ... <<<"$s"

  1. 便携性

    如您所见,<<<在 POSIX sh 中不可用;这是 bash 和 zsh 中也可用的 ksh 扩展。

    也就是说,如果您需要可移植性,多行等价物就在不远处:

    ... <<EOF
    $s
    EOF
    
  2. 磁盘使用情况

    目前由 bash 实现(并且作为实现细节可能会发生变化),<<<创建一个临时文件,填充它,并从中重定向。如果你的TEMPDIR不在内存文件系统上,这可能会更慢,或者可能会产生困惑。

  3. 处理开销

    管道,如 echo foo | ... , 创建一个 subshel​​l -- 它派生出一个全新的进程,负责运行 echo然后退出。当你运行时 result=$(echo "$s" | ...) ,然后该管道本身位于父 shell 的子 shell 中,并且那个 shell 的输出由父 shell 读取。

    现代的 unixlikes 付出了巨大的努力来制作 fork()尽可能降低子流程的开销,但即便如此,在循环中完成的操作中它也会累加起来——在 Cygwin 等平台上,它可能更为重要。

  4. echo漏洞

    最后但并非最不重要的 -- <<<"$s"将表示变量 s 的任何内容准确地说,除了它可以添加尾随换行符。相比之下,echo在其指定行为中有很大的回旋余地:它可以接受反斜杠扩展或不接受取决于是否符合标准的可选 XSI 扩展(以及是否存在广泛但完全不兼容的扩展 -e 和/或运行时禁用它的标志);使用 -n 避免添加尾随换行符的能力 |不受标准保证; &C。即使您使用的是管道,也最好使用 printf :

    # emit *exactly* the contents of "$s", with no newline added
    printf '%s' "$s" | ...
    
    # emit the contents of "$s", with an added trailing newline
    printf '%s\n' "$s" | ...
    
    # emit the contents of "$s", with '\t', '\n', '\b' &c replaced, and no added newline
    printf '%b' "$s" | ...
    

关于bash - 在字符串上运行 sed,使用 "echo"+ "pipe"优于 "<<<"的好处,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41899075/

相关文章:

regex - 行的一部分上的 Sed 正则表达式

java - 没有 System.out 怎么办,在控制台上打印?

bash - 如何在 bash 脚本中正确捕获 SIGQUIT?

linux - 为什么我的 shell 命令使用弯引号/智能引号不起作用?

bash - 删除字符串最后一个大小写之前的所有行

正则表达式在 OS X 终端中批量重命名文件

linux - 拆分以分号分隔的单词

regex - 使用 match 在只有 bash 的字符串中查找子字符串

haskell - 为什么 Haskell 中没有 IO 转换器?

c++ - 自己的输出流(mock cout)