Як видалити символ нового рядка в кінці файлу?


35

Дозвольте мені зрозуміти про персонаж нового рядка:

$ echo Hello > file1 ; cat file1
Hello
$ echo -n  Hello > file2 ; cat file2
Hello$ 

Тут ви бачите, що file1нове значення має в кінці, тоді як file2ні.

Тепер припустимо, що я один file:

$ cat file
Hello
Welcome to
Unix
$

І я хочу додати and Linuxв кінці файлу, потім echo " and Linux" >> fileбуде доданий у новий рядок. Але я хочу, щоб останній рядок бувUnix and Linux

Отже, для того, щоб обійти, я хочу видалити символ нового рядка в кінці файлу. Тому як видалити символ нового рядка в кінці файлу?


6
Не видаляйте його, просто використовуйте текстовий редактор. sed '$s/$/ and linux/'
123

Відповіді:


29

Якщо ви хочете лише додати текст до останнього рядка, це дуже просто з sed. Замініть $(відповідність шаблону в кінці рядка) текстом, який ви хочете додати, лише на рядки в діапазоні $(що означає останній рядок).

sed '$ s/$/ and Linux/' <file >file.new &&
mv file.new file

який в Linux можна скоротити до

sed -i '$ s/$/ and Linux/' file

Якщо ви хочете видалити останній байт з файлу, Linux (точніше GNU coreutils) пропонує truncateкоманду, що робить це дуже просто.

truncate -s -1 file

POSIX спосіб це зробити dd. Спочатку визначте довжину файлу, а потім обріжте його на один байт менше.

length=$(wc -c <file)
dd if=/dev/null of=file obs="$((length-1))" seek=1

Зауважте, що обидва вони беззастережно усікають останній байт файлу. Ви можете спочатку перевірити, чи це новий рядок:

length=$(wc -c <file)
if [ "$length" -ne 0 ] && [ -z "$(tail -c -1 <file)" ]; then
  # The file ends with a newline or null
  dd if=/dev/null of=file obs="$((length-1))" seek=1
fi

9
Набагато краще спосіб , щоб видалити символ кінця рядка є perl -pi -e 'chomp if eof' myfile. У порівнянні з truncateабо ddвін не залишить вас зі зламаним файлом, якщо myfileб насправді не було нових рядків.
Привіт-Ангел

2
@ Привіт-Ангел Чи можу рекомендувати написати це як відповідь? Я думаю, це була б дуже гарна відповідь.
Саймон Форсберг

@SimonForsberg дякую, зробили .
Привіт-Ангел

17

Хоча ви можете видалити символ нового рядка з рядка tr -d '\n':

$ echo -e "Hello"
Hello
$ echo -e "Hello" | tr -d '\n'
Hello$

Ви можете видалити символ нового рядка в кінці файлу, використовуючи наступний простий спосіб:

  1. head -c -1 file

    Від man head:

    -c, --bytes=[-]K
              print the first K bytes of each file; with the leading '-',
              print all but the last K bytes of each file
    
  2. truncate -s -1 file

    від man truncate:

    -s, --size=SIZE
              set or adjust the file size by SIZE
    

    SIZE is an integer and optional unit (example: 10M is 10*1024*1024).
    Units are K, M, G, T, P, E, Z, Y (powers of 1024) or KB, MB, ... (powers of 1000).
    
    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 file | tee fileбезпечно? Не вдалося teeврізати файл перед запуском?
iruvar

1
@ 1_CR Дійсно. Дві сторони труби починаються паралельно, справа в тому, хто виграє гонку. Оскільки teeфайл має відкрити лише той час, коли headвін повинен читати та записувати його вміст, teeна практиці виграє гонку, за винятком інколи дуже маленьких файлів.
Жиль "ТАК - перестань бути злим"

2
Це не видаляє останній новий рядок, він видаляє всі нові рядки. ІМО досить велика різниця.
Привіт-Ангел

10

Ви можете досягти цього за допомогою perl як:

perl -pi -e 'chomp if eof' myfile

У порівнянні з цим truncateабо ddне вийде зі зламаним файлом, якщо myfileнасправді не було нових рядків.

(відповідь будується з коментаря , і на основі цієї відповіді )


Дякую! Цей умовний метод видалення трейлінг нового рядка ідеальний.
xer0x

3

Ось один із способів sed- в останньому ( $) рядку файлу шукайте та замінюйте що-небудь і все ( .*) на "все, що вам відповідає", а потім "і Linux":

sed '$s/\(.*\)/\1 and Linux/' file

Ще простішим рішенням, з люб’язності Ісаака , є:

sed '$s/$/ and Linux/' file

Це замінює (символічний) кінець рядка заданим текстом.


Ісаак, мені подобається ця пропозиція! Це простіше / очевидніше. Відповідь я оновлю. Дякую!
Джефф Шаллер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.