How to fix “No newline at end of file” warning for

2019-01-14 04:11发布

I have a huge number of source files that are all lacking a newline at the end.

How do I automatically add a newline to the end of each of them?

Some may already have a newline, so it should only be added if necessary.

I'm probably not looking for code, per se, but just something I can run in Terminal to add the necessary newlines (or some kind of programming or development tool).

11条回答
时光不老,我们不散
2楼-- · 2019-01-14 04:57

Below is my bash script solution. It first checks that the file is a text file. Then, if it's a text file, it uses tail and od (octal dump) to see if the last character is the newline character. If it isn't, then it appends a newline using echo:

item="$1"

if file "$item" | egrep '\btext\b' > /dev/null
then
    if ! tail -c 1 "$item" | od -b -A n | egrep '\b012\b' > /dev/null
    then
        echo "(appending final newline to ${item})"
        echo >> "$item"
    fi
fi
查看更多
Animai°情兽
3楼-- · 2019-01-14 04:57

Due To command localization Tim and Norman answer Shall be improved using 'LANG=C' prefix to have a chance to match 'No newline' pattern with every system having any regional parameters

This ensures an ending empty line to every file put on the command line of this script :

 #!/bin/sh -f
 for i in $* ; do  echo $i; \
 if LANG=C diff /dev/null "$i" | tail -1 | \
  grep '^\\ No newline' > /dev/null; then echo >> "$i"; \
 fi; done

And this script detects files lacking of it :

 #!/bin/sh -f
 for i in $* ; do \
 if LANG=C diff /dev/null "$i" | tail -1 | \
  grep '^\\ No newline' > /dev/null; then  echo $i; \
 fi; done
查看更多
ら.Afraid
4楼-- · 2019-01-14 05:00

A simple fix for files that are "missing" newline at end of file is simply sed; the following fixes the file "in-place" (using the "-i" option):

find . -type f -exec sed -i -e '$a\' {} \; -print 

Explanation: find all files (-type f), run sed, change the files in-place (-i), given the following (-e) script/expression, which matches the end of the file ($), and perform the "append" action (a\), but don't actually specify any text to append (nothing after the \) which is going to add a newline to the end of the file, but only if it's missing. Prints all files found (fixed or not), which is probably unnecessary.

Main caveat is that sed features vary across platforms, so -i and -e may or may not be supported / the same; e.g. older Unix, or MacOS oddities may require slightly different syntax.

查看更多
劳资没心,怎么记你
5楼-- · 2019-01-14 05:00

Try ex-way:

ex -s +"bufdo wq" *.c

And recursively (with a new globbing option enabled):

ex -s +"bufdo wq" **/*.c

This is equivalent to vi -es. Change *.c to extension of your interest.

The ex/vi would automatically append newline on save if it's not present.

查看更多
何必那么认真
6楼-- · 2019-01-14 05:04

I'm surprised nobody has mentioned that many simple text-processing tools like Awk will add a newline as a side effect. Here is a simple loop which will overwrite a file only if a newline was actually added.

for f in *; do
    awk 1 "$f" >tmp
    cmp -s tmp "$f" || mv tmp "$f"
done
rm -f tmp

(The temporary file is obviously a bit of a wart.)

IDEone demo: http://ideone.com/HpRHcx

查看更多
登录 后发表回答