Удаление символа новой строки в конце файла
Чтобы удалить все новые строки, вы можете:
tr -d '\n' < days.txt
cat days.txt | tr -d '\n'
но как бы вы использовали tr
для удаления только новой строки в конце/конце текстового файла?
Я не обязательно укажу только последний.
Ответы
Ответ 1
Воспользуйтесь тем, что a) символ новой строки находится в конце файла и b) символ имеет размер 1 байт: используйте команду truncate
для сокращения файла на один байт:
# 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$
Вы также можете перевернуть размер и математику в одну строку:
truncate -s $(($(stat -c '%s' foo)-1)) foo
Ответ 2
Более простое решение, чем принятое:
truncate -s -1 <<file>>
На странице усеченного человека:
-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.
Ответ 3
Если вы уверены, что последний символ является новой строкой, это очень просто:
head -c -1 days.txt
head -c -N
означает все, кроме последних N байтов
Ответ 4
Я думаю, что ваш лучший выбор - Perl:
perl -0pe 's/\n\Z//' days.txt
-0
заставляет perl рассматривать весь файл как одну большую строку. -p
говорит ему распечатать эту строку после запуска программы на ней. И -e
говорит: "вот программа для запуска".
Регулярное выражение \n\Z
соответствует новой строке, но только если это последний символ в строке. И s/\n\Z//
говорит, что нужно заменить такой символ новой строки вообще ничего, удалив его.
Приведенная выше команда выводит новую версию файла, но вместо этого вы можете изменить существующую, добавив -i
("in -p lace"), опционально с суффиксом, который будет использоваться для именования резервной копии файл перед его изменением:
perl -i.bak -0pe 's/\n\Z//' days.txt
Это решение безопасно в том, что если последний символ не является новой строкой, он не будет затронут. Другие решения, которые просто удаляют последний байт, независимо от того, что может повредить такой файл.
Ответ 5
Попробуйте выполнить следующую команду:
sed '$ { /^$/ d}' days.txt
Вы можете прочитать это как: "проверить, является ли последняя строка пустой строкой, если это так удалить эту строку".
Я тестировал в обоих случаях: сначала с файлом, имеющим новую строку в конце, а в другой раз с файлом, заканчивающимся чем-то другим.