Чтобы удалить все новые строки, вы можете:
tr -d '\n' < days.txt
cat days.txt | tr -d '\n'
но как бы вы использовали tr
для удаления только новой строки в конце/конце текстового файла?
Я не обязательно укажу только последний.
Чтобы удалить все новые строки, вы можете:
tr -d '\n' < days.txt
cat days.txt | tr -d '\n'
но как бы вы использовали tr
для удаления только новой строки в конце/конце текстового файла?
Я не обязательно укажу только последний.
Воспользуйтесь тем, что 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
Более простое решение, чем принятое:
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.
Если вы уверены, что последний символ является новой строкой, это очень просто:
head -c -1 days.txt
head -c -N
означает все, кроме последних N байтов
Я думаю, что ваш лучший выбор - 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
Это решение безопасно в том, что если последний символ не является новой строкой, он не будет затронут. Другие решения, которые просто удаляют последний байт, независимо от того, что может повредить такой файл.
Попробуйте выполнить следующую команду:
sed '$ { /^$/ d}' days.txt
Вы можете прочитать это как: "проверить, является ли последняя строка пустой строкой, если это так удалить эту строку". Я тестировал в обоих случаях: сначала с файлом, имеющим новую строку в конце, а в другой раз с файлом, заканчивающимся чем-то другим.