Bagaimana cara menghapus karakter baris baru di akhir file?

35

Izinkan saya menjelaskan tentang karakter baris baru:

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

Di sini Anda dapat melihat yang file1memiliki karakter baris baru di akhir sedangkan yang file2belum.

Sekarang misalkan saya punya satu file:

$ cat file
Hello
Welcome to
Unix
$

Dan saya ingin menambahkan and Linuxdi akhir file, kemudian echo " and Linux" >> fileakan ditambahkan ke baris baru. Tapi saya ingin baris terakhir sebagaiUnix and Linux

Jadi, Untuk mengatasi ini, saya ingin menghapus karakter baris baru di akhir file. Karena itu Bagaimana cara menghapus karakter baris baru di akhir file?

Pandya
sumber
6
Jangan hapus itu, cukup gunakan editor teks. sed '$s/$/ and linux/'
123

Jawaban:

29

Jika semua yang ingin Anda lakukan adalah menambahkan teks ke baris terakhir, sangat mudah dengan sed. Ganti $(pencocokan pola di akhir baris) dengan teks yang ingin Anda tambahkan, hanya pada baris dalam rentang $(yang berarti baris terakhir).

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

yang di Linux dapat disingkat

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

Jika Anda ingin menghapus byte terakhir dalam sebuah file, Linux (lebih tepatnya GNU coreutils) menawarkan truncateperintah, yang membuatnya sangat mudah.

truncate -s -1 file

Cara POSIX untuk melakukannya adalah dengan dd. Pertama-tama tentukan panjang file, kemudian potong menjadi kurang satu byte.

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

Perhatikan bahwa keduanya tanpa syarat memotong byte terakhir file. Anda mungkin ingin memeriksa apakah itu adalah baris baru terlebih dahulu:

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
Gilles 'SANGAT berhenti menjadi jahat'
sumber
9
Cara yang jauh lebih baik untuk menghapus baris baru adalah perl -pi -e 'chomp if eof' myfile. Dibandingkan dengan truncateatau ddtidak akan meninggalkan Anda dengan file yang rusak jika myfilesebenarnya tidak ada baris baru.
Hi-Angel
2
@ Hi-Angel Bolehkah saya merekomendasikan penulisan itu sebagai jawaban? Saya pikir itu akan menjadi jawaban yang sangat bagus.
Simon Forsberg
@SimonForsberg terima kasih, sudah selesai .
Hi-Angel
17

Meskipun demikian, Anda dapat menghapus karakter baris baru dari baris dengan tr -d '\n':

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

Anda dapat menghapus karakter baris baru di akhir file menggunakan cara mudah berikut:

  1. head -c -1 file

    Dari 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

    dari 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.
Pandya
sumber
apakah head -c -1 file | tee fileaman? Tidak akan teememotong file sebelum memulai?
iruvar
1
@ 1_CR Memang. Kedua sisi pipa mulai paralel, itu masalah siapa yang memenangkan perlombaan. Karena teehanya perlu membuka file, sedangkan headharus membaca dan menulis isinya, teedalam praktiknya akan memenangkan perlombaan kecuali kadang-kadang untuk file yang sangat kecil.
Gilles 'SANGAT berhenti menjadi jahat'
2
Ini tidak menghapus baris baru terakhir, ini menghapus semua baris baru. Perbedaan IMO cukup besar.
Hi-Angel
10

Anda dapat mencapai ini dengan perl sebagai:

perl -pi -e 'chomp if eof' myfile

Dibandingkan truncateatau ddini tidak akan meninggalkan Anda dengan file yang rusak jika myfilesebenarnya tidak ada baris baru.

(jawabannya dibangun dari komentar , dan berdasarkan jawaban ini )

Hai Malaikat
sumber
Terima kasih! Metode penghapusan bersyarat ini membuntuti baris baru adalah sempurna.
xer0x
3

Inilah satu cara dengan sed- pada baris terakhir ( $) file, cari dan ganti apa saja ( .*) dengan "apa pun yang Anda cocokkan" diikuti oleh "dan Linux":

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

Solusi yang bahkan lebih sederhana, milik Ishak , adalah:

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

Ini menggantikan end-of-line (simbolis) dengan teks yang diberikan.

Jeff Schaller
sumber
Isaac, saya suka saran itu! Lebih sederhana / lebih jelas. Saya akan memperbarui jawabannya dengan itu. Terima kasih!
Jeff Schaller