Распечатать файл без добавления завершающей новой строки с помощью awk

Я использую awk для обработки некоторых программных файлов, удаляя разделы отладки. Некоторые из этих файлов не имеют завершающей новой строки. Я хотел бы, чтобы awk печатал файл построчно, с новыми строками, но без добавления дополнительной новой строки в конце, если ее нет.

E.g.

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. Но тогда он вместо этого пропускает новую строку из каждой строки.


person Chris Middleton    schedule 05.01.2016    source источник
comment
Почему? Файлы исходного кода без новой строки в конце считаются плохой практикой.   -  person hek2mgl    schedule 05.01.2016
comment
@hek2mgl hek2mgl Лично я бы тоже предпочел увидеть его в конце, но инструментам Windows все равно.   -  person Tom Fenech    schedule 05.01.2016
comment
@TomFenech По крайней мере, git будет жаловаться на это, в том числе и в Windows. Кстати, в Linux довольно сложно даже создать файл без новой строки в конце. :)   -  person hek2mgl    schedule 05.01.2016
comment
@ hek2mgl hek2mgl Я согласен с тем, что файлы исходного кода должны иметь новую строку в конце, но в случае, если они забыты и/или мы их не преобразовали, я бы хотел, чтобы скрипт все еще работал. BBEdit (в OS X) по умолчанию не вставляет новую строку в конце, поэтому я бы не сказал, что для этого требуется взлом. Однако у него есть параметр Убедитесь, что файл заканчивается разрывом строки, который, вероятно, следует проверить.   -  person Chris Middleton    schedule 05.01.2016
comment
Если GNU awk использует RT для вывода того же терминатора или его отсутствия, что и на входе. gnu.org/software/gawk/manual/html_node/ gawk-split-records.html   -  person dave_thompson_085    schedule 05.01.2016
comment
Я не уверен, что смогу полностью следовать за вами, но в любом случае используйте print вместо printf "%s", $0. В противном случае вы удалите любые разрывы строк..   -  person hek2mgl    schedule 05.01.2016
comment
@ hek2mgl Существующий скрипт использует print. (Извините, если это было неясно.) То, что выше, было моей демонстрацией вашей работы по решению проблемы с новой строкой. Использование print - это то, что вызывает проблему с добавлением новой строки, когда ее нет в оригинале. [[ОТРЕДАКТИРОВАНО сообщение, чтобы сделать его менее запутанным]]   -  person Chris Middleton    schedule 05.01.2016
comment
Я бы просто оставил его как print, но удалил завершающую новую строку (временно, если она есть) перед выполнением команды cmp. Просто сравните файлы, не принимая во внимание возможный перевод строки в конце.   -  person hek2mgl    schedule 05.01.2016


Ответы (2)


Вы можете просто использовать тот факт, что 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
person hek2mgl    schedule 05.01.2016
comment
Спасибо, это очень хорошее решение проблемы. Я попытался найти способ обойти это с помощью awk, но оказалось, что изнутри (стандартного) awk действительно невозможно сказать, заканчивается ли он новой строкой или нет. - person Chris Middleton; 05.01.2016

Измените свои 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

person karakfa    schedule 05.01.2016
comment
RT – это функция, ограниченная gawk: завершающая новая строка с awk%23comment56978477_34615809"> stackoverflow.com/questions/34615809/ - person hek2mgl; 05.01.2016
comment
Приятно знать, что есть способ. Жаль, что я не использую версию GNU. - person Chris Middleton; 05.01.2016