Cómo reemplazar múltiples espacios por una pestaña

27

Tengo algunos archivos de texto que contienen algunas columnas separadas por varios espacios, pero en cambio necesito una sola pestaña como separador. ¿Es posible hacer en Bash?

usuario desconocido
fuente
Gracias por el gran aporte, pero tengo algunos espacios individuales dentro de una columna, por lo que debo evitar tabular un solo espacio. perdón por eso, es información.
user_unknown

Respuestas:

31

Para convertir secuencias de más de un espacio en una pestaña, pero deje solo espacios individuales :

sed 's/ \+ /\t/g' inputfile > outputfile

Para hacer esto para varios archivos:

for inputfile in *
do
    sed 's/ \+ /\t/g' "$inputfile" > tmpfile && mv tmpfile "$inputfile"
done

o

for inputfile in *
do
    sed -i.bak 's/ \+ /\t/g' "$inputfile"
done

o

find . -type f -exec sed -i.bak 's/ \+ /\t/g' {} \;
Pausado hasta nuevo aviso.
fuente
sed: -e expression #1, char 1: unknown command: `.'
Aaron Franke
@AaronFranke: ¿Qué comando intentaste? Ninguno de los ejemplos en mi respuesta debería producir ese error.
Pausado hasta nuevo aviso.
Lo siento, debería haberlo aclarado. El findde abajo.
Aaron Franke
@AaronFranke: a GNU sedno le gusta tener un espacio antes de la extensión de la copia de seguridad. He editado mi respuesta. Gracias por el informe
Pausado hasta nuevo aviso.
7

Si tu personaje tiene varias pestañas, también puedes usar tr -s:

-s, --squeeze-repeats   replace each input sequence of a repeated character
                        that is listed in SET1 with a single occurrence

Por ejemplo:

my_file.txt | tr -s " "

Todos los espacios en blanco se convertirán en uno.

usuario597119
fuente
Esto no es lo que está pidiendo OP.
RonJohn
5

Puede usar sedpara reemplazar varios espacios con una pestaña .:

Ejemplo para reemplazar uno o más espacios con una pestaña:

cat spaced-file | sed 's/ \+/\t/g' > tabbed-file
IvanGoneKrazy
fuente
El OP dijo que el número de espacios era variable , por lo que no creo que esta solución funcione.
Mikel
@Mikel. Ups Gracias por señalar eso. He editado la publicación para permitir la coincidencia de espacios variables.
IvanGoneKrazy
La respuesta más útil aquí.
Luís de Sousa
3

La respuesta más fácil usando solo bashes:

while read -r col1 col2 col3 ...; do
    echo -e "$col1\t$col2\t$col3..."
done <file

Si hay un número variable de columnas, puede hacerlo, pero solo funcionará bash, no sh:

while read -r -a cols; do
    (
        IFS=$'\t'
        echo "${cols[*]}"
    )
done <file

p.ej

while read -r -a cols; do
    (
        IFS=$'\t'
        echo "${cols[*]}"
    )
done <<EOF
a b   c
d   e    f
  g h i
EOF

produce:

a   b   c
d   e   f
g   h   i

(hay una pestaña entre cada una, pero es difícil de ver cuando la pego aquí)

También puede hacerlo usando sedo tr, pero observe que el manejo de espacios en blanco al inicio produce resultados diferentes.

sed:

$ sed 's/  */\t/g' << EOF
a b   c
d   e    f
  g h i
EOF
a       b       c
d       e       f
        g       h       i

tr:

$ tr -s ' ' '\t' <<EOF
a b   c
d   e    f
  g h i
EOF
a       b       c
d       e       f
        g       h       i
Mikel
fuente
2

perl -p -i -e 's/\s+/\t/g' *.txt

RedGrittyBrick
fuente
2

Pruebe el siguiente script de SED:

 sed 's/  */<TAB>/g' <spaces-file > tabs-file

Donde <TAB> está presionando la tecla TAB.

mdpc
fuente
0

Esta es una solución muy simple:

    sed -E 's/\s+/\t/g' your_file > new_file

Básicamente, sed funciona de esta manera (sed 's / old_pattern / new_pattern / g'). En este caso, el patrón anterior es "\ s +", que significa encontrar el espacio "s" una o más veces "+" y la barra diagonal inversa "\" para interpretar eso como una expresión regular.
El nuevo patrón es la pestaña "\ t", que está escrita en formato de expresión regular y la "g" aplica el reemplazo a todas las líneas "globalmente".

Waleed Omer
fuente
1
Hola y bienvenidos a superusuario. Debe tomarse el tiempo para explicar su solución. Para alguien que no esté familiarizado con los sistemas * nix, sed y expresiones regulares, esto parece un montón de personajes extraños.
Mogget