while循环不会仅遍历所有代码行吗?

时间:2018-06-20 10:20:07

标签: bash shell loops awk

我有一个内容如下的文件

[path-to-file] [filesize]
/home/jochen/project/tests/test_m.py 8888
/home/jochen/project/tests/test_url.py 2453
/home/jochen/project/tests/testsupport/init.py 0
/home/jochen/project/tests/testsupport/test.py 5766
我想使用bash脚本进行操作的

作为输出,我希望将文件内容分开:

$ the filesize
$ a sum: filesizesum 
$ the filepath

我玩弄各种表达式,这是循环的当前版本:

while read k ; 
    do   
            awk '{print $2 }'; #Filesize
            awk '{ p += $2}; { print p }'; # Filesize sum up to here
            echo $k | awk '{print $1 }'; # Filepath
    done < FileWithInputData

我的麻烦是: 我可以删除dodone之间的3条代码行中的2条,其余行按预期在循环内工作。因此,每行似乎对我来说都是可以的。 但是当我使用两行或全部三行的组合时,行为会改变:只有第一行在起作用,而循环不在另一行中运行。

但是我不相信我需要运行三个不同的循环来实现这一目标。

我找不到另一个提供解决方案的线程,如果我写了重复的文章,请重定向我。我希望我能解释清楚我的麻烦所在。

感谢您的帮助。

1 个答案:

答案 0 :(得分:4)

这些在do...done中出现:

do
  awk '{print $2 }'; #Filesize
  awk '{ p += $2}; { print p }'; # Filesize sum up to here
  ...
done

不做任何事情,因为他们没有从stdin获得任何输入,也没有文件要处理。选择一种呼叫awk的方式:

  • program | awk '{...}' # reads from stdin
  • awk '{...}' file # processes a file
  • awk 'BEGIN{...} # all code within the BEGIN block

目前,他们基本上一直挂着等待丢失的输入。

好消息是您根本不需要bash循环。 Awk本身(可以是一个循环)迭代给定文件的所有记录。简而言之,您只需要:

$ awk '{print $1,p+=$1,$2}' file

例如:

$ echo -e 1 path1\\n2 path2\\n3 path3 | awk '{print $1,p+=$1,$2}'
1 1 path1
2 3 path2
3 6 path3

或者,如果您希望每个项目都单独一行,请添加BEGIN{OFS=ORS}

$ echo -e 1 path1\\n2 path2\\n3 path3 | awk 'BEGIN{OFS=ORS}{print $1,p+=$1,$2}'
1
1
path1
2
3
path2
3
6
path3