¿Cómo elimino el carácter de nueva línea al final del archivo?

35

Déjame aclarar sobre el carácter de nueva línea:

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

Aquí puede ver que file1tiene un carácter de nueva línea al final, mientras que file2no.

Ahora supongamos que tengo uno file:

$ cat file
Hello
Welcome to
Unix
$

Y quiero agregar and Linuxal final del archivo, luego echo " and Linux" >> filese agregará a la nueva línea. Pero quiero la última línea comoUnix and Linux

Entonces, para evitarlo, quiero eliminar el carácter de nueva línea al final del archivo. Por lo tanto, ¿cómo elimino el carácter de nueva línea al final del archivo?

Pandya
fuente
66
No lo elimine, solo use un editor de texto. sed '$s/$/ and linux/'
123

Respuestas:

29

Si todo lo que quiere hacer es agregar texto a la última línea, es muy fácil con sed. Reemplace $(coincidencia de patrón al final de la línea) por el texto que desea agregar, solo en las líneas del rango $(lo que significa la última línea).

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

que en Linux se puede acortar a

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

Si desea eliminar el último byte de un archivo, Linux (más precisamente GNU coreutils) ofrece el truncatecomando, que lo hace muy fácil.

truncate -s -1 file

Una forma POSIX de hacerlo es con dd. Primero determine la longitud del archivo, luego trúnquelo a un byte menos.

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

Tenga en cuenta que ambos truncan incondicionalmente el último byte del archivo. Es posible que desee comprobar que es una nueva línea primero:

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 'SO- deja de ser malvado'
fuente
99
Mucho mejor manera de eliminar un salto de línea final es perl -pi -e 'chomp if eof' myfile. Comparado truncateo ddno te dejará con un archivo roto si en myfilerealidad no tiene líneas nuevas.
Hola Ángel,
2
@ Hola, Ángel. ¿Puedo recomendar escribir eso como respuesta? Creo que esa sería una muy buena respuesta.
Simon Forsberg
@SimonForsberg gracias, hecho .
Hola Ángel el
17

Sin embargo, puede eliminar el carácter de nueva línea de la línea tr -d '\n':

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

Puede eliminar el carácter de nueva línea al final del archivo utilizando la siguiente manera fácil:

  1. head -c -1 file

    De 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

    de 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
fuente
es head -c -1 file | tee fileseguro? ¿No teetruncaría el archivo antes de comenzar?
iruvar
1
@ 1_CR De hecho. Los dos lados de la tubería comienzan en paralelo, se trata de quién gana la carrera. Como teesolo tiene que abrir el archivo, mientras que headtiene que leer y escribir su contenido, teeen la práctica ganará la carrera, excepto en ocasiones para archivos muy pequeños.
Gilles 'SO- deja de ser malvado'
2
Esto no elimina la última línea nueva, elimina todas las líneas nuevas. OMI una gran diferencia.
Hola Ángel,
10

Puede lograr esto con perl como:

perl -pi -e 'chomp if eof' myfile

En comparación con truncateo ddesto no va a dejar con un archivo roto si myfiletenía saltos de línea en realidad no se arrastran.

(la respuesta se construye a partir del comentario y se basa en esta respuesta )

Hola angel
fuente
¡Gracias! Este método condicional de eliminación es el final de línea nueva es perfecto.
xer0x
3

Aquí hay una manera con sed: en la última $línea ( ) del archivo, busque y reemplace cualquier cosa y todo ( .*) con "lo que coincida" seguido de "y Linux":

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

Una solución aún más simple, cortesía de Isaac , es:

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

Esto reemplaza el final de línea (simbólico) con el texto dado.

Jeff Schaller
fuente
Isaac, me gusta esa sugerencia! Es más simple / más obvio. Actualizaré la respuesta con ella. ¡Gracias!
Jeff Schaller