Bash脚本循环输入

时间:2011-09-03 01:14:48

标签: bash loops

我正在做以下,基本上有效。 该脚本尝试将一些行插入到文件中以重写它。

但它正在剥离所有空白行以及所有行填充。 主要问题是它不处理文件的最后一行。 我不确定为什么。

     while read line; do
        <... process some things ...>
        echo ${line}>> "${ACTION_PATH_IN}.work"
     done < "${ACTION_PATH_IN}"

可以采取哪些措施来解决这个问题?

4 个答案:

答案 0 :(得分:5)

while IFS= read -r line; do
    ## some work
    printf '%s\n' "$line" >> output
done < <(printf '%s\n' "$(cat input)")
  • 空的IFS告诉read不要去除前导空格和尾随空格。
  • read -r可防止EOL反斜杠创建续行。
  • 双引号参数替换("$line")以防止shell对其值进行单词拆分和通配。
  • 使用printf '%s\n'代替echo,因为在处理类似-e-n等的值时它是可靠的。
  • < <(printf '%s\n' "$(cat input)")是一种丑陋的LF终止input内容的方式。其他结构也是可能的,具体取决于您的要求(管道而不是来自流程替换的重定向,如果您的整个while可以在子shell中运行)。
    如果你在处理它之前确保它是LF终止的,那可能会更好。

答案 1 :(得分:3)

最好的是,使用awk之类的工具代替shell的while循环。首先,awk用于解析/操作文件,因此要处理大文件,awk具有优势。其次,你不必关心你是否有最后一个换行符(对你的情况而言)。

因此相当于你的while read循环:

awk '{
  # process lines
  # print line > "newfile.txt"
}' file 

答案 2 :(得分:1)

不读最后一行的一个可能原因是该文件不以换行符结尾。总的来说,我希望它能够发挥作用,但这可能就是原因。

在MacOS X(10.7.1)上,我得到了这个输出,这是你看到的行为:

$ /bin/echo -n Hi
Hi$ /bin/echo -n Hi > x
$ while read line; do echo $line; done < x
$

明显的解决方法是确保文件以换行符结尾。

答案 3 :(得分:0)

首先,使用

echo "$line" >> ...

注意引号。如果你不放它们,shell本身将删除填充。

至于最后一行,很奇怪。它可能与文件的最后一行是否被\n终止有关(这是一个很好的做法,几乎任何编辑器都会为你做这件事)。