Como substituir vários espaços por uma guia

27

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

Usuário desconhecido
fonte
Obrigado pela ótima entrada, mas eu tenho alguns espaços únicos dentro de uma coluna, por isso tenho que evitar tabular um único espaço. desculpe por isso, é informação.
User_unknown

Respostas:

31

Para converter seqüências de mais de um espaço em uma guia, mas deixe espaços individuais em paz :

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

Para fazer isso em 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' {} \;
Pausado até novo aviso.
fonte
sed: -e expression #1, char 1: unknown command: `.'
Aaron Franke
@AaronFranke: Que comando você tentou? Nenhum dos exemplos na minha resposta deve produzir esse erro.
Pausado até novo aviso.
Desculpe, eu deveria ter esclarecido. A findum na parte inferior.
Aaron Franke
@AaronFranke: O GNU sednão gosta de ter espaço antes da extensão do backup. Eu editei minha resposta. Obrigado pelo relatório.
Pausado até novo aviso.
6

Se seu personagem possui 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.

user597119
fonte
Não é isso que o OP está pedindo.
RonJohn
5

Você pode usar sedpara substituir vários espaços por uma guia:

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

cat spaced-file | sed 's/ \+/\t/g' > tabbed-file
IvanGoneKrazy
fonte
O OP disse que o número de espaços era variável , então não acho que essa solução funcione.
Mikel
@Mikel. Opa Obrigado por apontar isso. Eu editei a postagem para permitir a correspondência de espaços variáveis.
IvanGoneKrazy 02/02
Resposta mais útil aqui.
Luís de Sousa
3

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 ele funcionará apenas bash, não 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

(existe uma guia entre cada uma, mas é difícil ver quando colo aqui)

Você também pode fazer isso usando sedor tr, mas observe que o manuseio de 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
Mikel
fonte
2

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

RedGrittyBrick
fonte
2

Experimente o seguinte script SED:

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

Onde <TAB> está pressionando a tecla TAB.

mdpc
fonte
0

Esta é uma solução muito simples:

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

O sed funciona basicamente dessa maneira (sed 's / old_pattern / new_pattern / g'). Nesse caso, o padrão antigo é "\ s +", o que significa encontrar espaço "s" uma ou mais vezes "+" e a barra invertida "\" para interpretar isso como expressão regular.
O novo padrão é a guia "\ t", escrita em formato de expressão regular, e o "g" aplica a substituição a todas as linhas "globalmente".

Waleed Omer
fonte
1
Olá e bem-vindo ao superusuário. Você deve reservar um tempo para explicar sua solução. Para alguém não familiarizado com sistemas * nix, sed e expressões regulares, isso parece uma pilha de caracteres estranhos.
Mogget 03/04