如何在sh中使用`<<(tail ...)`而不是bash?

时间:2019-05-22 11:04:53

标签: shell unix sh

我想创建一个脚本来读取.txt文件。这是我的代码:

while IFS= read -r lines
do
  echo "$lines"
done < <(tail -n +2 filename.txt)

我尝试了很多类似的事情:

<<(tail -n +2 in.txt)
< < (tail -n +2 in.txt)
< (tail -n +2 in.txt)
<(tail -n +2 in.txt)
(tail -n +2 in.txt)

我希望从第二行开始打印,但是却出现错误:

Syntax error: redirection unexpected

2 个答案:

答案 0 :(得分:2)

如果您只想忽略第一行,则根本没有充分的理由使用tail

{
    read -r first_line
    while IFS= read -r line; do
      printf '%s\n' "$line"
    done
} <filename.txt

使用read来消耗第一行会保持原始文件指针不变,因此以下代码可以直接从文件读取,而不是从附加到tail程序输出的FIFO中读取;因此,其开销较低。


如果您想使用tail,对于出现的特定情况,您无需使用流程替换(<(...)),而只需使用管道进入您的while循环中。请注意,这会带来严重的副作用,因为您在循环中设置的所有变量在退出后将不再可用。 BashFAQ #24(以跨壳方式)对此进行了记录。

tail -n +2 filename.txt | while IFS= read -r line
do
  printf '%s\n' "$line"
done

答案 1 :(得分:1)

如答案中所说 POSIX shell equivalent to <() 您可以使用命名管道来模拟流程替换 POSIX。您的脚本如下所示:

#!/usr/bin/env sh

mkfifo foo.fifo

tail -n +2 filename.txt >foo.fifo &

while IFS= read -r lines
do
    echo "$lines"
done < foo.fifo

rm foo.fifo