Cómo eliminar la última columna de un archivo en Linux

Quiero eliminar la última columna de un archivo txt, mientras que no sé cuál es el número de columna es. ¿Cómo puedo hacer esto?

Ejemplo:

Entrada:

1223 1234 1323 ... 2222 123 1233 1234 1233 ... 3444 125 0000 5553 3455 ... 2334 222 

Y quiero que mi salida sea :

1223 1234 1323 ... 2222 1233 1234 1233 ... 3444 0000 5553 3455 ... 2334 

Comentarios

  • Hay muchas formas de hacer esto .. por favor agregue un ejemplo y su resultado esperado de él ..
  • @heemayl ok, lo hice
  • Gracias..¿están las pestañas de columnas separadas o espacios separados?
  • @heemayl el espacio es deliminador
  • cut suena como la herramienta para el trabajo.

Responder

Con awk:

awk "NF{NF-=1};1" <in >out 

o:

awk "NF{NF--};1" <in >out 

o:

awk "NF{--NF};1" <in >out 

Aunque esto parece vudú, funciona. Hay tres partes para cada uno de estos comandos awk.

La primera es NF, que es una condición previa para la segunda parte. NF es una variable que contiene el número de campos en una línea. En AWK, las cosas son verdaderas si «no son 0 o una cadena vacía "". Por lo tanto, la segunda parte (donde NF se reduce) solo ocurre si NF no es 0.

La segunda parte (ya sea NF-=1 NF-- o --NF) es simplemente restar uno de la variable NF. Esto evita que se imprima el último campo, porque cuando cambia un campo (eliminando el último campo en este caso), awk reconstruye $0, concatena todos los campos separados por espacios de forma predeterminada . $0 ya no contenía el último campo.

La parte final es 1. No es mágico, solo se usa como una expresión que significa true. Si una expresión awk se evalúa como verdadera sin ninguna acción asociada, la awk acción predeterminada es print $0 .

Comentarios

  • @JJoao: Ah, gracias, me olvidé de --. Una nota, actualmente, necesitas ;1 para que sea compatible con POSIX.
  • Mi instinto inicial sería usar un bucle for, pero esto es mucho más conciso e inteligente.
  • Es ' s vale la pena señalar que si ' estás usando un delimitador no predeterminado, ' Tendremos que hacer algunos cambios. Suponiendo que , es su delimitador: awk -F',' 'BEGIN { OFS = FS }; NF { NF -= 1 }; 1' < in > out
  • El efecto de disminuir NF es un comportamiento indefinido de POSIX; obtendrá salida diferente según el awk que ' esté ejecutando. Algunos awks eliminarán el último campo como desee, otros no harán nada en absoluto y otros podrían informar un error de sintaxis o cualquier otra cosa.

Responder

Usando grep con PCRE:

$ grep -Po ".*(?=\s+[^\s]+$)" file.txt 1223 1234 1323 ... 2222 1233 1234 1233 ... 3444 0000 5553 3455 ... 2334 

Usando GNU sed:

$ sed -r "s/(.*)\s+[^\s]+$/\1/" file.txt 1223 1234 1323 ... 2222 1233 1234 1233 ... 3444 0000 5553 3455 ... 2334 

Comentarios

  • @ramin Seguro. . ¿Podrías preguntarlo como una nueva pregunta (así es como funciona este sitio) 🙂
  • @ramin? ¿Te da alguna ¿restricción de tiempo o alguna advertencia?
  • ¡Dice que esto está fuera de la pregunta estándar!
  • @ramin Ok..permítame contactar a un administrador, tal vez ellos puedan ayudarlo con eso .. Por cierto, ¿revisó algún control de calidad anterior con respecto a su pregunta? Es posible que la pregunta ya se haya formulado y respondido.
  • No ' t hagas preguntas súper básicas como " ¿cómo puedo cambiar el nombre de un archivo en Linux ". Use Google.

Respuesta

Usando Perl:

perl -lane "$,=" ";pop(@F);print(@F)" in 

Usando rev + cut:

rev in | cut -d " " -f 2- | rev 

Respuesta

Usando GNU sed:

sed -r "s/\s+\S+$//" input.txt 

En general, este funciona con BSD sed en OSX, así como con GNU sed:

sed "s/[[:space:]]\{1,\}[^[:space:]]\{1,\}$//" input.txt 

Respuesta

Si el delimitador es siempre un solo carácter (por lo que dos o más delimitadores consecutivos designan campos vacíos), podría head solo la primera línea de su archivo de entrada, cuente los delimitadores ( n delimitadores significa que la cantidad de campos es n+1) luego use cut para imprimir desde el 1 st campo hasta el n th campo (penúltimo), p. ej. con entrada delimitada por tabuladores:

n=$(head -n 1 infile | tr -dc \\t | tr \\t \\n | wc -l) cut -f1-$n infile > outfile 

o p. ej.con un archivo csv :

n=$(head -n 1 infile | tr -dc , | tr , \\n | wc -l) cut -d, -f1-$n infile > outfile 

Ejecutaré algunos puntos de referencia más tarde si tengo tiempo, pero con una entrada enorme, creo que esto La solución debería ser más rápida que otras soluciones que usan expresiones regulares, ya que esta realiza un procesamiento mínimo en la primera línea para obtener el número de campos y luego usa cut que está optimizado para este trabajo.

Respuesta

Portabilidad, puede usar cualquiera de estos:

sed "s/[[:space:]]*[^[:space:]]*$//" file awk "{sub(/[[:space:]]*[^[:space:]]*$/,"")}1" file 

Respuesta

Usando vim:

Abrir archivo en vim

vim <filename> 

Vaya a la primera fila, en caso de que el cursor se coloque en cualquier otro lugar.

gg 

Cree una macro llamada «q» qq, que va al final de la línea actual $, luego vuelve al último espacio F (F mayúscula, seguida de ESPACIO literal) luego borre desde la posición actual hasta el final de la línea D vaya a la siguiente línea j y detenga la grabación de macros con q.

qq$F Djq 

Ahora podemos repetir nuestra macro con @q para cada línea.
También podemos presionar @@ para repetir la última macro o incluso más fácil:

99@q 

para repetir la macro 99 veces.
Nota: El número no debe coincidir exactamente con las líneas.

Respuesta

Para personas que tienen un problema similar pero con diferentes separadores de campo, este awk conservará el separador de campo correctamente:

$ cat file foo.bar.baz baz.bar.foo $ awk -F"." "sub(FS $NF,x)" file foo.bar baz.bar 

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *