错误:将输出传输到命令时重定向不明确

错误:将输出传输到命令时重定向不明确

在脚本中重定向的输出:

$ ls -ltr |awk '{print $9}'

default.txt
dfah.txt
fruit.txt
fruit_prices.txt
dfh.txt
header.txt
testfile.txt
topoutput.txt

在 shell 上编写的脚本:

while read line
do 
var=`sed -e 's/\.txt/txt\.txt/' $line`
 echo $var
 done < `ls -ltr |awk '{print $9}'`

出现错误:

-bash: `ls -ltr |awk '{print $9}'`: ambiguous redirect

专家可以帮我看看上面的代码中如何发生不明确的重定向吗?

答案1

尝试

ls -ltr |awk '{print $9}' | while read line
do 
  var=`sed -e 's/\.txt/txt\.txt/' $line`
  echo $var
done 

你发出了这样的命令

while read line ; do
  ...
 done < a b c d

无法解析的

答案2

看起来你正在尝试做

while read line
do
  ...
done < <(ls -ltr | awk '{print $9}')

但为什么?管道输送到while read line(阿彻玛的回答)更清晰、更便携。

好的,为了让我的答案更完整:Zoltán Böszörményi 指出,

ls -ltr | awk '{print $9}' | while read line
do
  ...
done

在 bash(和其他一些 shell)中,在子 shell 中运行 的主体while,因此 shell 状态(例如 shell 变量)的状态更改不会在循环之外持续存在。以下地方对此进行了更全面的讨论:

< <(…)本答案顶部的代码是避免该问题的一种方法。


但另一件事

你正在做的ls -ltr | awk '{print $9}'。这看起来像是按修改日期/时间的顺序列出文件然后提取文件名的拼凑。有几个问题:

  • 对于包含空格的文件名,此操作会失败。
  • ls通过告诉你生成,你正在为自己做额外的工作列出信息(文件模式、所有者、大小等),然后在您不需要首先生成它时将其删除。

您可以通过省略来解决这两个问题l选项 ls,并省略 awk

while read line
do
  ...
done < <(ls -tr)

以空格开头或结尾的文件名可能仍然存在问题。

也可以看看为什么不应该解析 ls(1) 的输出

答案3

因为“cat file | while read line ...”在子shell中运行“while”的主体,shell变量在子shell之外将不可见,但“while read line ; do ... ; did < <(command )”在同一个 shell 中运行它。

这是我的测试文件:

$ cat fruits.txt
apple
cherry
pear
plum

观察两个脚本的差异及其结果:

$ cat a.sh
#!/bin/bash

FOUND=0

while read fruit ; do
    case $fruit in
    cherry)
        echo yay, cherry found
        FOUND=1
        ;;
    esac
done < <(cat fruits.txt)
echo cherry found: $FOUND

$ ./a.sh
yay, cherry found
cherry found: 1

$ cat b.sh 
#!/bin/bash

FOUND=0

cat fruits.txt | while read fruit ; do
    case $fruit in
    cherry)
        echo yay, cherry found
        FOUND=1
        ;;
    esac
done
echo cherry found: $FOUND
$ ./b.sh 
yay, cherry found
cherry found: 0

答案4

你还可以这样做:

while read line; do
    var=`echo "$line" |sed -e 's/\.txt/txt\.txt/'`
    echo $var
done <<_EOT_
$(ls -ltr | awk '{print $9}')
_EOT_

相关内容