输入正在跟随
Title: Aoo Boo
Author: First Last
我正在尝试输出
Aoo Boo, First Last, "
使用像这样的awk
awk 'BEGIN { FS="[:[:space:]]+" }
/Title/ { sub(/^Title: /,""); t = $0; } # save title
/Author/{ sub(/^Author: /,""); printf "%s,%s,\"\n", t, $0}
' t.txt
但输出就像是“irst Last。基本上它从句子的开头打印出所有内容。
但如果我将$ 0更改为$ 2,则输出为预期值Boo,Last,"
为什么不正确?什么是正确的方法?
答案 0 :(得分:2)
如果要使用Unix实用程序,则需要删除文本文件中的Windows行结尾。
如果你很幸运,你会发现你安装了dos2unix
程序,而你只需要这样做:
dos2unix t.txt
如果没有,您可以使用tr
:
tr -d '\r' < t.txt > new_t.txt
作为参考,正在发生的事情是Windows文件在每一行的末尾都有\r\n
(实际上, CR 控制代码后跟 NL 控制代码)。在Linux上,行以\n
结束,因此\r
是数据的一部分;当你打印出来时,终端将其解释为“回车”,它将光标移动到当前行的开头,而不是前进到下一行。由于t
的值以\r
结尾,因此以下文字将覆盖t
的值。
它适用于$2
,因为您已重新分配FS
以包含[:space:]
;字段分隔符的定义比awk默认值更慷慨,因为它包含\r
和\f
,它们都不是默认字段分隔符。因此,$2
不包含\r
,但$0
包含{。}}。
答案 1 :(得分:0)
这假设标题或名称中没有冒号......
awk -F': *' '
$1=="Title" {
sub(/[^[:print:]]/,"");
t=$2;
}
$1=="Author" {
sub(/[^[:print:]]/,"");
printf("%s, %s\n", t, $2);
}
' inputfile.txt
这可以通过查找标题并将其存储在变量中,然后找到作者并将其用作触发器来根据您的格式打印所有内容。您可以根据需要更改格式。
如果线上有额外的冒号,可能会破坏,因为冒号用于分割字段。如果您的输入与您的示例不符,它也可能会中断。
在这个例子中,最重要的可能是sub(...)
函数,它们剥离了不可打印的字符,比如rici注意到的回车符。正则表达式[^[:print:]]
匹配“可打印”字符,回车符不是。如果这些脚本存在, sub 会将它们遗忘,但如果不存在则不应该受到伤害。