使用awk打印文件时如何不添加尾随换行符

3
我正在使用awk处理一些程序文件,删除调试部分。其中有一些文件没有尾随的换行符。我希望awk逐行打印文件,并在每行末尾添加换行符,但是如果末尾没有额外的换行符,则不需要添加一个额外的换行符。
例如:
a
b // no newline after the "b"

被转换成了这样:

a
b<NEWLINE>

我不想添加换行符的原因是我正在尝试使用cmp --silent $file $file_without_debug_sections来确定是使用原始文件还是新文件。而我关心的原因是我想限制编译器输出中具有调试扩展名的文件数量。仅在它们有所不同的情况下使用非调试版本还清楚地表明了哪些文件是通过"删除调试部分"过程更改的。
因此,总结一下,我该如何让awk逐行处理文件,但如果不存在换行符,则不添加换行符?
我的当前代码如下:
{    
    if ($0 ~ /^[ \t]*\/\/[ \t]*\/\*[ \t]*begin[ \t]+debug[ \t]*$/) { 
        print "/* begin debug"; 
    } else if ($0 ~ /^[ \t]*\/\/[ \t]*end[\ t]+debug[\t ]*\*\/[ \t]*$/) { 
        print "end debug */";
    } else print;
}

我尝试将末尾的print替换为printf "%s", $0。但这样会从每一行中省略一个换行符。


1
@TomFenech 至少 git 会抱怨,即使在 Windows 上也是如此。顺便说一句,在 Linux 上,甚至在文件末尾没有换行符的情况下生成文件也是相当不规范的做法。 :) - hek2mgl
@hek2mgl 我同意源代码文件应该在结尾处有一个换行符,但如果忘记了和/或我们还没有转换它们,我希望脚本仍然能够工作。BBEdit(在OS X上)默认情况下不会在结尾处插入换行符,因此我不认为它需要“hack”。但是,它确实有一个“确保文件以换行符结束”的设置,这应该已经被检查过了。 - Chris Middleton
1
如果使用GNU awk,可以使用RT来输出与输入中找到的相同终止符或缺乏任何终止符。https://www.gnu.org/software/gawk/manual/html_node/gawk-split-records.html - dave_thompson_085
@hek2mgl,现有的脚本确实使用了print。(如果不清楚,请原谅。)上面是我尝试解决换行问题时展示的工作方式。使用print导致在原始内容中不存在换行符的情况下添加换行符的问题。【编辑】帖子,使其更清晰易懂。 - Chris Middleton
我会直接使用 print,但在执行 cmp 命令之前删除换行符(如果存在的话)。简单比较文件时不考虑末尾可能有的换行符。 - hek2mgl
显示剩余3条评论
2个回答

3

将您的print line语句更改为printf "%s%s", line, RT

例如

$ seq 3 > s3
$ head -c -1 s3 > s3nn                      # remove last newline
$ awk '$1=$1{printf "%s%s", $0, RT}' s3nn
1
2
3$ awk '$1=$1' s3nn
1
2
3
$ cat s3nn
1
2
3$

在你的情况下,没有参数的print等同于print $0

1
RT 是仅限于 gawk 的一个功能:https://dev59.com/XJLea4cB1Zd3GeqP5rNu#b8PnnYgBc1ULPQZFF1U0 - hek2mgl
很高兴知道有一种方法。太遗憾了,我没有使用GNU版本。 - Chris Middleton

1
您可以简单地利用awk自动在末尾添加换行符的特性,如下所示:
# Let's say file1 does not contain a newline at the end. Since
# awk will add a newline at the end if it is missing, file1_debug
# WILL contain a newline at the end.
awk -f remove_debug.awk file1 > file1_debug

# Use awk again before comparing the files, this makes sure that when
# we compare them, both files have a newline at the end.
if cmp --silent <(awk '1' file1) <(awk '1' file1_debug) ; then
    echo "The files are the same"
else
    echo "The files differ"
fi

谢谢,这是一个非常好的解决方案。我试图用awk想出一个解决方法,但似乎从(标准)awk中无法确定它是否以换行符结尾。 - Chris Middleton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接