【问题标题】:How to iterate over each output of awk with sh?如何用sh迭代awk的每个输出?
【发布时间】:2016-08-16 01:30:54
【问题描述】:

我有一个 test.sh 文件,它通过文本文件 test.bed 进行操作:

1   31  431
1   14  1234
1   54  134
2   435 314
2   314 414

while read line;do
    echo $line  
    # ... more code ... #
done < <(awk -F '\t' '$1 == 1 {print $0}' test.bed )

使用bash test.sh 运行它可以工作,但使用sh test.sh 会产生语法错误。我怎样才能使用sh 而不是bash 来完成上述操作?


它给出的错误是

test.sh: line 5: syntax error near unexpected token `<'
test.sh: line 5: `done < <(awk -F '\t' '$1 == 1 {print $0}' test.bed )'

【问题讨论】:

  • 错误是什么?
  • @vidit test.sh:第 5 行:意外标记附近的语法错误 &lt;' test.sh: line 5: done
  • 您使用的是哪个环境?我没有遇到过这种错误。能否请您粘贴完整的脚本?
  • &lt;( ... ) 不是sh 的有效语法(或bash 兼容模式下的bash)。
  • 阅读why-is-using-a-shell-loop-to-process-text-considered-bad-practice,您可能会重新考虑您的设计。

标签: bash shell awk sh


【解决方案1】:

Process Substitutionbash 扩展 - 不是由 POSIX 指定的。这是sh 兼容..

#!/bin/sh

awk -F '\t' '$1 == 1 {print $0}' test.bed  | while read line; do
echo $line
    # ... more code ... #
done

【讨论】:

  • 这充满了错误,考虑到 test.bed 的内容、运行工具的目录、环境设置等的各种组合,这些错误会咬你一口。它还有多余的 awk 代码,但这并不重要. IF 像这样的 shell 循环是必要的,那么编写它的方式就是awk -F '\t' '$1 == 1' test.bed | while IFS= read -r line; do echo "$line"; done。如果您的 shell 支持它以获得额外的稳健性,请使用 printf 而不是 echo
  • 不,我说方法是错误的,即使方法是正确的,您的答案仍然是错误的实现方法。请参阅我的第一条评论。
  • 如果原始脚本以#!/bin/bash 开头,它将起作用。我尽量避免在脚本中使用 bashisms,但原始海报没有理由这样做。
猜你喜欢
  • 1970-01-01
  • 2011-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-16
  • 1970-01-01
  • 2020-02-18
相关资源
最近更新 更多