这里发生了什么事? Shell编程

时间:2012-03-15 05:18:53

标签: shell sh

我在这里有这个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" 

2 个答案:

答案 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中运行。