¿Cómo recorto los espacios en blanco iniciales y finales de cada línea de algún resultado?

Me gustaría eliminar todos los espacios iniciales y finales y las pestañas de cada línea en una salida.

¿Existe una herramienta simple como trim ¿Podría canalizar mi salida a?

Archivo de ejemplo:

test space at back test space at front TAB at end TAB at front sequence of some space in the middle some empty lines with differing TABS and spaces: test space at both ends 

Comentarios

  • Para cualquiera que busque aquí una solución para eliminar nuevas líneas, ese es un problema diferente. Por definición, una nueva línea crea una nueva línea de texto. Por lo tanto, una línea de texto no puede contener una nueva línea. La pregunta que desea hacer es cómo eliminar una nueva línea del principio o del final de una cadena: stackoverflow.com/questions/369758 , o cómo eliminar el espacio en blanco líneas o líneas que son solo espacios en blanco: serverfault.com/questions/252921

Respuesta

awk "{$1=$1;print}" 

o más corto:

awk "{$1=$1};1" 

Se recortarían los espacio final o caracteres de tabulación 1 y también comprimir secuencias de tabulaciones y espacios en un solo espacio.

Eso funciona porque cuando asigna algo a uno de los campos , awk reconstruye todo el registro (como lo imprime print) uniendo todos los campos ($1, …, $NF) con OFS (espacio por defecto).

1 (y posiblemente otro carácter en blanco s según la configuración regional y la awk implementación)

Comentarios

  • Punto y coma en El segundo ejemplo es superfluo. Podría usar: awk '{$1=$1}1'
  • @Brian, no, el ; es necesario en la sintaxis estándar de awk
  • Interesante … No hay punto y coma compatible con gawk, mawk y OS X ‘ s awk. (Al menos para mis versiones (1.2, 4.1.1 y 20070501, respectivamente)
  • Lo único que ‘ no me gusta de este enfoque es que perder espacios repetidos dentro de la línea. Por ejemplo, echo -e 'foo \t bar' | awk '{$1=$1};1'
  • echo ' hello ' | xargs

Respuesta

El comando se puede condensar así si «estás usando GNU sed:

$ sed "s/^[ \t]*//;s/[ \t]*$//" < file 

Ejemplo

Aquí está el comando anterior en acción.

$ echo -e " \t blahblah \t " | sed "s/^[ \t]*//;s/[ \t]*$//" blahblah 

Puede usar hexdump para confirmar que el comando sed está eliminando los caracteres deseados correctamente.

$ echo -e " \t blahblah \t " | sed "s/^[ \t]*//;s/[ \t]*$//" | hexdump -C 00000000 62 6c 61 68 62 6c 61 68 0a |blahblah.| 00000009 

Clases de caracteres

También puede usar nombres de clases de caracteres en lugar de enumerar literalmente los conjuntos como este, [ \t]:

$ sed "s/^[[:blank:]]*//;s/[[:blank:]]*$//" < file 

Ejemplo

$ echo -e " \t blahblah \t " | sed "s/^[[:blank:]]*//;s/[[:blank:]]*$//" 

La mayoría de las herramientas GNU que hacen uso de expre regular ssions (regex) admiten estas clases (aquí con su equivalente en la configuración regional C típica de un sistema basado en ASCII (y solo allí)).

 [[:alnum:]] - [A-Za-z0-9] Alphanumeric characters [[:alpha:]] - [A-Za-z] Alphabetic characters [[:blank:]] - [ \t] Space or tab characters only [[:cntrl:]] - [\x00-\x1F\x7F] Control characters [[:digit:]] - [0-9] Numeric characters [[:graph:]] - [!-~] Printable and visible characters [[:lower:]] - [a-z] Lower-case alphabetic characters [[:print:]] - [ -~] Printable (non-Control) characters [[:punct:]] - [!-/:-@[-`{-~] Punctuation characters [[:space:]] - [ \t\v\f\n\r] All whitespace chars [[:upper:]] - [A-Z] Upper-case alphabetic characters [[:xdigit:]] - [0-9a-fA-F] Hexadecimal digit characters 

Usando estos en lugar de conjuntos literales siempre parecen una pérdida de espacio, pero si le preocupa que su código sea portátil o tenga que lidiar con conjuntos de caracteres alternativos (piense internacional), es probable que desee utilizar los nombres de clase en su lugar .

Referencias

Comentarios

  • Tenga en cuenta que [[:space:]] no es equivalente a [ \t] en el caso general (Unicode, etc). [[:space:]] probablemente será mucho más lento (ya que hay muchos más tipos de espacios en blanco en Unicode que solo ' ' y '\t'). Lo mismo para todos los demás.
  • sed 's/^[ \t]*//' no es portátil. En realidad, POSIX incluso requiere eso para eliminar una secuencia de espacio, barra invertida o t caracteres, y que ‘ es lo que GNU sed también lo hace cuando POSIXLY_CORRECT está en el entorno.
  • ¿Qué sucede si quiero recortar caracteres de nueva línea? ‘ \ n \ n text \ n \ n ‘
  • Me gusta la solución sed debido a la falta de otros efectos secundarios como en la solución awk. La primera variación no funciona cuando la probé en bash en OSX jsut ahora, pero la versión de la clase de caracteres sí funciona: sed 's/^[[:blank:]]*//;s/[[:blank:]]*$//'
  • @EugeneBiryukov ver mi comentario sobre la publicación original

Respuesta

Los xargs sin argumentos hacen eso.

Ejemplo:

trimmed_string=$(echo "no_trimmed_string" | xargs) 

Comentarios

  • Esto también contrae varios espacios dentro una línea, que no se solicitó en la pregunta
  • @roaima – verdadero pero la respuesta aceptada también aprieta espacios (que no se solicitó en la pregunta). Creo que el problema real aquí es que xargs no se entregará si la entrada contiene barras invertidas y comillas simples.
  • @don_crissti que no ‘ Sin embargo, no significa que la respuesta aceptada responde correctamente a la pregunta tal como se hizo. Pero en este caso aquí no estaba ‘ t marcado como una advertencia, mientras que en la respuesta aceptada sí lo estaba. ‘ espero haber destacado el hecho en caso de que ‘ s sea de relevancia para un futuro lector.
  • También saltos en comillas simples, comillas dobles, caracteres de barra invertida. También ejecuta una o más invocaciones echo. Algunas implementaciones de eco también procesarán opciones y / o barras invertidas … Eso también solo funciona para entradas de una sola línea.

Responder

Según lo sugerido por Stéphane Chazelas en la respuesta aceptada, ahora puede
crear un script /usr/local/bin/trim:

#!/bin/bash awk "{$1=$1};1" 

y otorgue derechos ejecutables a ese archivo:

chmod +x /usr/local/bin/trim 

Ahora puede pasar cada salida a trim por ejemplo:

cat file | trim 

(para los comentarios a continuación: utilicé esto antes: while read i; do echo "$i"; done
que también funciona bien, pero tiene menos rendimiento)

Comentarios

  • Buena suerte si su archivo es enorme y / o contiene barras invertidas.
  • @don_crissti: ¿podría comentar un poco más? ¿Qué solución se ajusta mejor a archivos de gran tamaño, y ¿cómo podría modificar mi solución si el archivo contiene barras invertidas?
  • Usted ‘ tendrá que usar while read -r line para conservar las barras invertidas y incluso entonces … . En cuanto a archivos enormes / velocidad, en realidad, eligió la peor solución. No ‘ no creo que ‘ haya algo peor ahí fuera. Vea las respuestas en ¿Por qué usar un bucle de shell para procesar texto es una mala práctica? incluido mi comentario sobre la última respuesta donde agregué un enlace a un punto de referencia de velocidad. Las sed respuestas aquí están perfectamente bien en mi opinión y mucho mejores que read.
  • También puede agregar un alias en / etc / profile (o su ~ / .bashrc o ~ / .zshrc etc …) alias trim = » awk ‘ { \ $ 1 = \ $ 1}; 1 ‘ »
  • No es necesario bash, puede hacerlo #! /usr/bin/awk -f {$1=$1};1. (tenga cuidado con los nombres de archivo que contienen = caracteres)

Respuesta

Si almacena líneas como variables, puede usar bash para hacer el trabajo:

eliminar los espacios en blanco iniciales de una cadena:

shopt -s extglob echo ${text##+([[:space:]])} 

eliminar los espacios en blanco finales de una cadena:

shopt -s extglob echo ${text%%+([[:space:]])} 

eliminar todos los espacios en blanco de una cadena:

echo ${text//[[:space:]]} 

Comentarios

  • Eliminar todos los espacios en blanco de una cadena no es lo mismo que eliminar los espacios iniciales y finales (como en la pregunta).
  • Con mucho, la mejor solución: solo requiere integraciones de bash y no bifurcaciones de proceso externas.
  • Agradable. Los scripts se ejecutan MUCHO más rápido si ‘ no tienen que introducir programas externos (como awk o sed). Esto también funciona con las versiones » modernas » (93u +) de ksh.

Respuesta

sed -e "s/^[[:space:]]*//" -e "s/[[:space:]]*$//" 

Si «estás leyendo una línea en una variable de shell, read ya hace eso a menos que se indique lo contrario .

Comentarios

  • +1 para read. Por lo tanto, si canaliza mientras lee, funciona: cat file | while read i; do echo $i; done
  • @rubo excepto que en su ejemplo, la variable sin comillas también es reprocesada por el shell. Use echo "$i" para ver el verdadero efecto de read

Respuesta

Para eliminar todos los espacios iniciales y finales de una línea dada gracias a una herramienta «canalizada», puedo identificar 3 diferentes formas que no son completamente equivalentes. Estas diferencias se refieren a los espacios entre las palabras de la línea de entrada. Dependiendo del b esperado ehaviour, usted hará su elección.

Ejemplos

Para explicar las diferencias, consideremos esta línea de entrada ficticia:

" \t A \tB\tC \t " 

tr

$ echo -e " \t A \tB\tC \t " | tr -d "[:blank:]" ABC 

tr es realmente un comando simple. En este caso, borra cualquier espacio o carácter de tabulación.

awk

$ echo -e " \t A \tB\tC \t " | awk "{$1=$1};1" A B C 

awk elimina los espacios iniciales y finales y aprieta en un solo espacio cada espacio entre palabras.

sed

$ echo -e " \t A \tB\tC \t " | sed "s/^[ \t]*//;s/[ \t]*$//" A B C 

En este caso, sed elimina los espacios iniciales y finales sin tocar ningún espacio entre palabras.

Observación:

En el caso de una palabra por línea, tr hace el trabajo.

Comentarios

  • Nada de esto recorta las nuevas líneas finales / iniciales
  • +1 para obtener una lista de soluciones con su salida (a veces inesperada).
  • @ user61382 esto es bastante tarde, pero vea mi comentario en la publicación original.
  • @highmaintenance: use [:space:], en lugar de [: blank:], para el comando tr, como: ... | tr -d [:space:], para eliminar las nuevas líneas también. (ver: man tr)

Respuesta

sed es un gran herramienta para eso:

 # substitute ("s/") sed "s/^[[:blank:]]*//; # parts of lines that start ("^") with a space/tab s/[[:blank:]]*$//" # or end ("$") with a space/tab # with nothing (/) 

Puede usarlo para su caso ya sea en el texto, p. ej.

<file sed -e "s/^[[... 

o actuando «en línea» si su sed es GNU:

sed -i "s/..." file 

pero cambiar la fuente de esta manera es «peligroso», ya que puede ser irrecuperable cuando no funciona correctamente (¡o incluso cuando lo hace!), así que haga una copia de seguridad primero (o use -i.bak que también tiene la ventaja de ser portable a algunos sed s) BSD!

Respuesta

Una respuesta que puede comprender de un vistazo:

#!/usr/bin/env python3 import sys for line in sys.stdin: print(line.strip()) 

Bonificación: reemplace str.strip([chars]) con caracteres arbitrarios para recortar o usar .lstrip() o .rstrip() según sea necesario.

Me gusta rubo77 «sa nswer , guárdelo como script /usr/local/bin/trim y otorgue permisos con chmod +x.

Respuesta

Si la cadena que uno está tratando de recortar es corta y continua / contigua, simplemente puede pasarla como parámetro a cualquier función bash:

 trim(){ echo $@ } a=" some random string " echo ">>`trim $a`<<" Output >>some random string<< 

Responder

Escribí esta función de shell usando awk

awkcliptor(){ awk -e "BEGIN{ RS="^$" } {gsub(/^[\n\t ]*|[\n\t ]*$/,"");print ;exit}" "$1" ; } 

BEGIN{ RS="^$" }:
al principio antes de comenzar a analizar, establezca el registro
separador en ninguno es decir, trate toda la entrada como
un solo registro

gsub(this,that):
sustituya esta expresión regular por esa cadena

/^[\n\t ]*|[\n\t ]*$/:
de esa cadena captura cualquier espacio previo a la nueva línea y clase de tabulación
o publica el espacio de nueva línea y la clase de tabulación y los reemplaza con
cadena vacía

print;exit: luego imprima y salga

"$1":
y pase el primer argumento de la función a be
process by awk

cómo se usa:
copiar el código anterior, pegarlo en el shell y luego ingresar para
definir la función.
entonces puede usar awkcliptor como un comando con el primer argumento como el archivo de entrada

uso de muestra:

echo " ggggg " > a_file awkcliptor a_file 

salida:

ggggg 

o

echo -e "\n ggggg \n\n "|awkcliptor 

salida:

ggggg 

Comentarios

  • ¿Puede explicar la diferencia a solo awk '{$1=$1};1'?

Respuesta

Para aquellos de nosotros sin suficiente espacio en el cerebro para recordar la sintaxis sed oscura, simplemente invierta la cadena , corte el primer campo con un delimitador de espacio y vuelva a invertirlo.

cat file | rev | cut -d" " -f1 | rev 

Comentarios

  • Esto solo funciona si no hay más de un espacio delante de cada línea y no más de una palabra en cada línea.

Responder

trimpy () { python3 -c "import sys for line in sys.stdin: print(line.strip())" } trimsed () { gsed -e "s/^[[:space:]]*//" -e "s/[[:space:]]*$//" } trimzsh () { local out="$(</dev/stdin)" [[ "$out" =~ "^\s*(.*\S)\s*$" ]] && out="$match[1]" || out="" print -nr -- "$out" } # example usage echo " hi " | trimpy 

Bonificación: reemplace str.strip([chars]) con caracteres arbitrarios para recortar o usar o .rstrip() según sea necesario.

Responder

El comando translate funcionaría

cat file | tr -d [:blank:] 

Comentarios

  • Este comando no es correcto ya que elimina todos los espacios del archivo, no solo los espacios en blanco iniciales / finales.
  • @BrianRedbeard Tiene razón. Esta sigue siendo una respuesta útil para una cadena monolítica, sin espacios.

Respuesta

para el ejemplo de bash:

alias trim="awk "{\$1=\$1};1"" 

uso:

echo -e " hello\t\tkitty " | trim | hexdump -C 

resultado:

00000000 68 65 6c 6c 6f 20 6b 69 74 74 79 0a |hello kitty.| 0000000c 

Comentarios

  • La awk '{$1=$1};1' respuesta se dio hace mucho tiempo. La idea de convertirlo en un alias se sugirió en un comentario hace casi el mismo tiempo. Sí, puede tomar el comentario de otra persona y convertirlo en una respuesta. Pero, si lo hace, debe dar crédito a las personas que publicaron la idea antes que usted. Y esta es una extensión tan trivial de la respuesta aceptada que realmente no vale la pena molestarse.
  • La idea era crear un alias. No ‘ he visto esa respuesta antes.
  • Y lo segundo de la pila: » ¡Gracias por los comentarios! Los votos emitidos por aquellos con menos de 15 reputación se registran, pero no cambian la puntuación de la publicación mostrada públicamente. »

Deja una respuesta

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