質問

To remove all newlines you could, say:

tr -d '\n' < days.txt
cat days.txt | tr -d '\n'

but how would you use tr to remove just the newline at the end/bottom of a text file?

I'm not sure to specify just the last one.

役に立ちましたか?

解決 2

Take advantage of the fact that a) the newline character is at the end of the file and b) the character is 1 byte large: use the truncate command to shrink the file by one byte:

# a file with the word "test" in it, with a newline at the end (5 characters total)
$ cat foo 
test

# a hex dump of foo shows the '\n' at the end (0a)
$ xxd -p foo
746573740a

# and `stat` tells us the size of the file: 5 bytes (one for each character)
$ stat -c '%s' foo
5

# so we can use `truncate` to set the file size to 4 bytes instead
$ truncate -s 4 foo

# which will remove the newline at the end
$ xxd -p foo
74657374
$ cat foo
test$ 

You can also roll the sizing and math into a one line command:

truncate -s $(($(stat -c '%s' foo)-1)) foo

他のヒント

A simpler solution than the accepted one:

truncate -s -1 <<file>>

From the truncate man page (man truncate):

-s, --size=SIZE
    set or adjust the file size by SIZE
SIZE may also be prefixed by one of the following modifying characters:
    '+' extend by, '-' reduce by, '<' at most, '>' at least, '/' round down
    to multiple of, '%' round up to multiple of.

If you are sure the last character is a new-line, it is very simple:

head -c -1 days.txt

head -c -N means everything except for the last N bytes

I think your best bet is Perl:

perl -0pe 's/\n\Z//' days.txt

The -0 causes perl to treat the whole file as one big string. The -p tells it to print that string back out after running the program on it. And the -e says "here's the program to run".

The regular expression \n\Z matches a newline, but only if it's the last character in a string. And s/\n\Z// says to replace such a newline with nothing at all, deleting it.

The above command outputs the new version of the file, but you can instead modify the existing one by adding the -i ("in-place") option, optionally with a suffix that will be used to name a backup copy of the file before modifying it:

 perl -i.bak -0pe 's/\n\Z//' days.txt

This solution is safe in that if the last character is not a newline, it won't be touched. The other solutions which simply remove the last byte no matter what may corrupt such a file.

Try this command: sed '$ { /^$/ d}' days.txt

You can read it as: "check if last line is an empty line. if so delete this line". I tested with both cases: first with a file having a new line at the end and an other time with a file ending with something else.

Another Sed solution:

sed -z s/.$// days.txt

With the -z option, it interprets the file as a single long line (newlines are embedded as \n), then s matches the single character . before the end of line (= end of file) $, and changes it into nothing. No need for quoting the command.

If you are not sure the last character is a newline, then you do either of these:

sed -z s/\\n$// days.txt
sed -z 's/\n$//' days.txt
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top