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?


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' {} \;

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.


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

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


2

Experimente o seguinte script SED:

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

Onde <TAB> está pressionando a tecla TAB.


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".


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.