2013-05-03 20 views
14

Aby usunąć wszystkie znaki nowej linii ty mógłby powiedzieć:Usunięcie znak nowego wiersza na końcu pliku

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

ale jak byłoby użyć tr usunąć tylko nowej linii na końcu/dole pliku tekstowego?

Nie jestem pewien, aby określić tylko ostatni.

+0

możliwe duplikat (http [Jak mogę usunąć znak nowej linii, jeśli jest to ostatni znak w pliku?]: // stackoverflow.com/questions/1654021/how-can-i-delete-a-new-line-if-it-is-the-last-character-in-a-file) –

Odpowiedz

16

skorzystać z faktu, że: a) znak nowej linii jest na końcu pliku i b) postać jest 1 bajt duży: użyj komendy truncate się kurczyć plik o jeden bajt:

# 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$ 

można także toczyć zaklejanie i matematyki w poleceniu jeden wiersz:

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

Możesz po prostu użyć 'truncate -s -1' i zrobi to dla ciebie matematyka .. –

+0

@MarkReed odpowiedź jest najprostsza. –

+0

Łatwiejsze rozwiązania poniżej! –

10

myślę najlepiej jest Perl:

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

W -0 przyczyny perl traktować cały plik jako jeden wielki ciąg. -p mówi, aby wydrukować ten ciąg z powrotem po uruchomieniu programu na nim. I -e mówi "tutaj jest program do uruchomienia".

Wyrażenie regularne \n\Z dopasowuje znak nowej linii, ale tylko jeśli jest to ostatni znak w tym ciągu. I s/\n\Z// mówi, aby zastąpić taki nowy wiersz nic, usuwając go.

Powyższe polecenie wyprowadza nową wersję pliku, ale można zamiast tego zmodyfikować istniejącą, dodając opcję -i ("w miejscu"), opcjonalnie z sufiksem, który zostanie użyty do nazwania kopii zapasowej plik przed modyfikując go:

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

to rozwiązanie jest bezpieczne w że jeśli ostatni znak jest nie znak nowej linii, to nie będzie poruszony. Inne rozwiązania, które po prostu usuwają ostatni bajt, bez względu na to, co może uszkodzić taki plik.

+0

Przyjemny sposób na zrobienie tego przy pomocy perl – tonix

+0

Działa to na MacOS jako no, chyba że 'skracam' lub' head -c -1'. – codeforester

4

Spróbuj polecenia: sed '$ { /^$/ d}' days.txt

Możesz przeczytać to jako: "sprawdź, czy ostatnia linia jest pustą linią. jeśli tak, usuń ten wiersz ". Testowałem w obu przypadkach: najpierw z plikiem z nową linią na końcu i innym razem z plikiem kończącym się z czymś innym

+1

Jeszcze lepiej z trybem "sed" w miejscu: sed -i '$ {/^$/d}' days.txt – DreamFlasher

18

Jeśli jesteś pewien, że ostatnia postać jest znakiem new-line, to jest bardzo proste:

head -c -1 days.txt 

head -c -N oznacza wszystko z wyjątkiem ostatniego n bajtów

+7

ma 'head: liczba nielegalnych bajtów -1 'na OS X Yosemite 10.10.5 :( – talles

+0

to samo na MacOS High Sierra 10.13. 'Liczba nielegalnych bajtów' –

+0

Dla MacOS-a musisz" napar zainstalować coreutils "i użyć' ghead'. – dev

21

prostsze rozwiązanie niż przyjętym One:

truncate -s -1 <<file>> 

Od strony truncate człowieka:

-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.