如果我在bash中读取文件的最后一行,我怎么能理解?

时间:2013-02-19 23:16:26

标签: bash readfile line-by-line

我想逐行读取文件,编辑该行并将其放入新文件中:

while read my_line
do
    # doesn't handle the last OR
    printf "'%s'\$label OR " $my_line >> delivered 
done < "labels.txt"

不幸的是,通过遵循这种方法,我也在文件的最后一个元素之后添加了一个OR。

我认为在某种程度上我可以通过识别最后一行来处理这种情况:从手册页,当$?对于读取不同于0,那么我们有文件结束;但在这种情况下,我无法在循环中使用它来创建不同的printf指令。

有什么建议吗?

谢谢

4 个答案:

答案 0 :(得分:1)

你可以试试这个:

while read my_line
do
  printf "'%s'"
  read -t 0 && printf " OR "
done < "labels.txt" > delivered

第二个read(使用-t指定超时为0秒)仅在有可用输入但未使用任何输入时成功。打印完最后一行后,它将成功,因此您不会打印尾随的“OR”。

答案 1 :(得分:1)

这方面的经典解决方法是只添加一行0=1。制作'FOO' OR 'BAR' OR 0=1

{
while read my_line
do
    # doesn't handle the last OR
    printf "'%s'\$label OR " $my_line
done 
echo 0=1
} < "labels.txt" > delivered

这样做的另一个好处是将空输入文件转换为有效表达式0=1而不是空字符串。

答案 2 :(得分:1)

另一个有趣的解决方案,使用

$ cat file.txt
aaa
bbb
ccc
$ perl -pe 's/.*/\047$&\047/; !eof && s/\n/\$label OR /g' file.txt
'aaa'$label OR 'bbb'$label OR 'ccc'

这有一个非常清晰的语法的优点,不是吗?

  • -pe默认代表print(例如sed)&amp;假设while (<>) {}等效
  • \047代表单引号'
  • 的八进制表示
  • !eof代表if the EOF is not reached
  • s/// sed like substitution
  • 的基本框架

答案 3 :(得分:0)

headtail的简单解决方案:

$ cat test.txt
aa
bb
cc
dd
$ head -n -1 test.txt|sed "s/$/ OR/"; tail -n 1 test.txt
aa OR
bb OR
cc OR
dd

head读取除最后一行之外的文件,如-1所示的行数。然后sed在每行的末尾添加关键字,在搜索表达式中与$匹配。然后tail添加未修改的最后一行。

由于有两个命令,要将输出重定向到文件,您可以在子shell中运行它:

$ (head -n -1 test.txt|sed "s/$/ OR/"; tail -n 1 test.txt) > output