在脚本中重定向的输出:
$ 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 变量)的状态更改不会在循环之外持续存在。以下地方对此进行了更全面的讨论:
- 在 bash 中,
read
管道未设置值后, - 为什么我的变量在一个
while read
循环中是本地变量,但在另一个看似相似的循环中却不是? - BashFAQ/024:我在管道中的循环中设置变量。为什么循环结束后它们就消失了?或者,为什么我不能将数据传输到
read
? - 和这里, 这里 和 这里 在堆栈溢出上。
< <(…)
本答案顶部的代码是避免该问题的一种方法。
但另一件事
你正在做的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_