我正在做以下,基本上工作。 该脚本尝试在文件中插入一些行以重写它。Bash脚本通过循环输入循环
但它是剥离所有空行和所有行填充。 主要问题是它不处理文件的最后一行。 我不知道为什么。
while read line; do
<... process some things ...>
echo ${line}>> "${ACTION_PATH_IN}.work"
done < "${ACTION_PATH_IN}"
可以做些什么来解决这个问题?
我正在做以下,基本上工作。 该脚本尝试在文件中插入一些行以重写它。Bash脚本通过循环输入循环
但它是剥离所有空行和所有行填充。 主要问题是它不处理文件的最后一行。 我不知道为什么。
while read line; do
<... process some things ...>
echo ${line}>> "${ACTION_PATH_IN}.work"
done < "${ACTION_PATH_IN}"
可以做些什么来解决这个问题?
while IFS= read -r line; do
## some work
printf '%s\n' "$line" >> output
done < <(printf '%s\n' "$(cat input)")
read
不剥离的前缘和后空格。read -r
防止EOL中的反斜杠创建行延续。"$line"
)以防止shell对其值进行分词和匹配。printf '%s\n'
代替echo
,因为它处理值等像-e
,-n
等< <(printf '%s\n' "$(cat input)")
是LF的丑陋的方式终止的input
内容时是可靠的。其他结构也是可能的,这取决于你的要求(如果你的整个while
运行在一个子shell中,管道而不是从过程替换重定向)。 不读取最后一行的一个可能原因是该文件没有以换行符结束。总的来说,我希望它能够工作,但这可能是为什么。
在MacOS X(10.7.1),我得到这个输出,这是您所看到的行为:
$ /bin/echo -n Hi
Hi$ /bin/echo -n Hi > x
$ while read line; do echo $line; done < x
$
最明显的解决方法是,以确保该文件以换行符结束。
第一件事情,用
echo "$line" >> ...
注意引号。如果你不放它们,壳本身将会移除填充。
至于最后一行,这很奇怪。它可能与文件的最后一行是否由\n
终止有关(这是一个很好的做法,几乎所有的编辑都会为你做这件事)。
最好,使用一个工具,如awk
而不是shell的while
循环。首先,awk
是用于解析/操作文件,因此对于处理大文件,awk
具有优势。其次,你不必关心你是否有最后一个换行符(对于你的情况)。
因此您while read
回路的等效:
awk '{
# process lines
# print line > "newfile.txt"
}' file
如果'IFS'已设置为读取,不需要最后'printf',因为'read'实际上将读取所有的行逐字(包括空格),因为'cat'只是对文件内容没有任何影响,但将它们复制到管道中。 –
@Diego:'printf'foo \ n \ n bar'| bash -c'while IFS = read -r line;做printf“<<%s>> \ n”“$ line”; done''从不处理最终的非LF终止的“bar”行。来自流程替代的重定向中的'printf'是在那里添加一个尾随LF(如果原始内容没有一个;这不是关于保留空白,而是要正确处理最后一行。 –
@Diego:你是正确的,'read'将读取最终的非LF终止行,但它也返回非零值,它退出循环(因此这样的行绝不会被循环体处理)。 –