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?
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?
Respostas:
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: `.'
find
um na parte inferior.
sed
não gosta de ter espaço antes da extensão do backup. Eu editei minha resposta. Obrigado pelo relatório.
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.
Você pode usar sed
para 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
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 sed
or 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
perl -p -i -e 's/\s+/\t/g' *.txt
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".