paste <(cut -f 1-8 file) <(cut -f9- file | tr -d '\t')
Eu me pergunto o que é uma maneira mais simples de fazer isso:
awk 'NR > 1 {print $1"\t"$2"\t"$3"\t"$4"\t"$5"\t"$6"\t"$7"\t"$8"\t"$9$10$11$12$13$14$15$16}' file.in > file.out
que é simplesmente falando "concatene as colunas de 9 a 16 removendo as guias entre elas"
As colunas mescladas 9-16 se tornam "Notes", portanto, podem incluir espaços em branco.
A partir de hoje, existem 16 colunas, mas isso pode evoluir em mais / menos, se necessário. Eventualmente, a coluna 9 (9-16 concatenada) torna-se campo "notas".
Felicidades,
Xi
Assumindo algumas linhas de valores separados por tabulações, gerados desta forma:
% perl -E 'say join "\t", 1..8 for 1..3'
As várias colunas podem ser tratadas conforme necessário por meio das sinalizações adequadas e href="https://metacpan.org/pod/distribution/perl/pod/perlvar.pod"> variáveis e functions disponível em Perl.
% perl -E 'say join "\t", 1..8 for 1..3' \
| perl -pale '$_=join "\t", @F[0..3], join "", @F[4..7] if $. > 1'
1 2 3 4 5 6 7 8
1 2 3 4 5678
1 2 3 4 5678
%
Sim, de muitas maneiras. Eu testei os dois seguintes em um arquivo criado por:
perl -le 'next if $.==1; for(1..20){print join "\t",1..20 }' > file
É um arquivo com 20 linhas e 20 colunas separadas por tabulações.
Perl
perl -F'\t' -ale '$"="\t";print "@F[0..7]",@F[8..$#F]' file
Observe que isso une todos os campos do 10º ao fim. Se você quiser apenas participar de 9 a 16, use isto:
perl -F'\t' -ale '$"="\t"; print "@F[0..7]", @F[8..15], "\t@F[16..$#F]"' file
awk
awk -F'\t' 'NR>1{
for(i=1;i<9;i++){
printf "%s\t",$i
}
for(i=9;i<=NF;i++){
printf "%s",$i
}print ""
}' file
Como antes, isso unirá todas as colunas após o 10º. Se você quiser apenas participar de 9 a 16, use isto:
awk -F'\t' 'NR>1{
for(i=1;i<9;i++){
printf "%s\t",$i
}
for(i=9;i<=16;i++){
printf "%s",$i
}
for(i=17;i<=NF;i++){
printf "\t%s", $i
}
print ""
}' file
Concedido, as soluções awk
não são muito curtas, mas pelo menos você não precisa especificar todos os campos manualmente.
$ cat file | python -c "import sys
for line in sys.stdin: l=line.rstrip('\r\n').split('\t'); print('\t'.join(l[:9]) + ''.join(l[9:]))
"
s/(([^\t]*\t){8})/\n/
h
s/[^\n]*\n//
s/\t//g
G
s/([^\n]*)\n([^\n]*)\n.*//
Exemplo de uso:
$ sed -r "s/(([^\t]*\t){8})/\n/;h;s/[^\n]*\n//;s/\t//g;G;s/([^\n]*)\n([^\n]*)\n.*//" file
Explicação:
Suponha que file
seja
a b c d e f g h i j k l
O separador em file
é a guia.
sed
lê a linha atual.
a b c d e f g h i j k l
s/(([^\t]*\t){8})/\n/
divide a linha em duas partes.
a b c d e f g h \ni j k l
h
armazena espaço de padrão no espaço de espera.
a b c d e f g h \ni j k l
a b c d e f g h \ni j k l
s/[^\n]*\n//
remove a primeira parte do espaço padrão.
i j k l
a b c d e f g h \ni j k l
s/\t//g
remove as guias no espaço padrão.
ijkl
a b c d e f g h \ni j k l
G
acrescenta \n
e mantém espaço no espaço padrão.
ijkl\na b c d e f g h \ni j k l
a b c d e f g h \ni j k l
s/([^\n]*)\n([^\n]*)\n.*//
divide o espaço do padrão e o substitui pela segunda e primeira partes sem \n
.
a b c d e f g h ijkl
a b c d e f g h \ni j k l
sed
imprime o espaço do padrão.
É possível modificar o código e remover guias nas colunas do meio:
s/(([^\t]*\t){3})(([^\t]*\t){4})(.*)/\n\n/
h
s/[^\n]*\n([^\n]*)\n.*//
s/\t//g
G
s/([^\n]*)\n([^\n]*)\n([^\n]*)\n(.*)//
Com o GNU sed
(assumindo que os campos são delimitados por tabulações na entrada):
sed 's/\t//9g'
Exclui do 9º ao último caractere de tabulação em cada linha.
Se houver mais de 16 campos na entrada e você não quiser os adicionais:
cut -f 1-16 | sed 's/\t//9g'
awk:
awk -v OFS="\t" '{for (i=10; i<=NF; i++) $9 = $9 " " $i; NF = 9; print}' file
Os campos 10 até o final são anexados ao campo 9, em seguida, o número de campos é limitado ao primeiro 9 e a linha é impressa usando a tabulação como o separador do campo de saída.
Suponho que você queira que os campos concatenados sejam separados por um espaço.
Caso contrário, altere $9 " " $i
para $9 $i
Tags command-line awk sed shell-script