Como substituir vários espaços por uma guia

Como substituir vários espaços por uma guia

Tenho alguns arquivos de texto que contêm algumas colunas separadas por vários espaços, mas preciso de uma única guia como separador. É possível fazer no Bash?

Responder1

Para converter sequências demais de um espaçopara uma guia, masdeixe espaços individuais sozinhos:

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

Para fazer isso para vários arquivos:

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

ou

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

ou

find . -type f -exec sed -i.bak 's/ \+ /\t/g' {} \;

Use este formulário para MacOS (ou simplesmente para evitar escapar do +no Linux):

sed -E 's/ + /\t/g'

junto com outras opções, etc., necessárias nos exemplos acima.

Responder2

Se o seu personagem tiver várias guias, você também pode usar tr -s:

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

Por exemplo:

my_file.txt | tr -s " "

Todos os espaços em branco se tornarão um.

Responder3

Você pode usar sedpara substituir vários espaços por uma tabulação:

Exemplo para substituir um ou mais espaços por uma guia:

cat spaced-file | sed 's/ \+/\t/g' > tabbed-file

Responder4

A resposta mais fácil usando apenas bashé:

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

Se houver um número variável de colunas, você poderá fazer isso, mas só funcionará em bash, não em sh:

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

por exemplo

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

produz:

a   b   c
d   e   f
g   h   i

(há uma aba entre cada uma, mas é difícil ver quando colo aqui)

Você também poderia fazer isso usando sedou tr, mas observe que o tratamento dos espaços em branco no início produz 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

informação relacionada