2

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

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

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

我认为以某种方式我可以通过识别最后一行来处理这种情况:从手册页中,当 $? 因为 read 不同于 0,那么我们就有了文件结尾;但在这种情况下,我不能在循环中使用它来创建不同的 printf 指令。

有什么建议吗?

谢谢

4

4 回答 4

1

你可以试试这个:

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

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

于 2013-02-19T23:24:14.860 回答
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而不是空字符串的额外好处。

于 2013-02-19T23:26:56.053 回答
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)&假设while (<>) {}等价
  • \047代表单引号的八进制表示'
  • !eof代表if the EOF is not reached
  • s///类似 sed 的替换的基本骨架
于 2013-02-19T23:37:50.443 回答
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读取除最后一行之外的文件,如-1for 行数所示。然后sed在每行末尾添加关键字,该关键字在$搜索表达式中匹配。然后 tail 添加未修改的最后一行。

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

$ (head -n -1 test.txt|sed "s/$/ OR/"; tail -n 1 test.txt) > output
于 2013-02-20T09:38:42.753 回答