我在这里有这个shell脚本,它正在做我想做的事情。但是,当我尝试在末尾打印出变量时,附加到小,中或大的$ file变量不会显示在std输出中。 shell在这里做了什么,我该怎么做才能解决它?
#!/bin/sh
# sorts txt files into small, medium and large
# depending on number of lines
# small <= 10
# medium <= 100
# large > 100
small="Small Files:"
medium="Medium Files:"
large="Large Files:"
for txtFile in *.txt
do
wc -l $txtFile
done |
while read lineCount file
do
if [ $lineCount -lt 10 ]
then
small="$small $file"
elif [ $lineCount -lt 100 ]
then
medium="$medium $file"
else
large="$large $file"
fi
done
echo "$small"
echo "$medium"
echo "$large"
答案 0 :(得分:3)
使用管道时,管道的各个阶段作为单独的进程运行,并且分配的变量不会传播回主进程。你可以这样做:
small="Small Files:"
medium="Medium Files:"
large="Large Files:"
for txtFile in *.txt
do
wc -l $txtFile
done | (
while read lineCount file
do
if [ $lineCount -lt 10 ]
then
small="$small $file"
elif [ $lineCount -lt 100 ]
then
medium="$medium $file"
else
large="$large $file"
fi
done
echo "$small"
echo "$medium"
echo "$large"
)
括号使while循环和echo语句分组到一个进程中,因此保留变量值。
您可以在一个更简单的示例中看到此效果:
x=5;echo | x=6;echo $x
将打印5,而
x=5;echo | (x=6;echo $x)
将打印6。
答案 1 :(得分:1)
您也可以使用进程替换,尽管可读性有所不同:
while read lineCount file; do
if [ $lineCount -lt 10 ]; then
small="$small $file"
elif [ $lineCount -lt 100 ]; then
medium="$medium $file"
else
large="$large $file"
fi
done < <(wc -l *txt)
这是有效的,因为它删除了管道,因此while循环在当前shell中运行。