Na sua versão de SunOS
nawk
(ou quanto a awk
) deve ser capaz de fazer o truque
nawk -F';' 'BEGIN{OFS=";"}{print($1,$2,$3,$(NF-1),$(NF))}' file.txt
Eu pedi quase o mesmo pergunta já , mas, desta vez, quero recuperar os elementos X mais recentes de uma linha de um arquivo CSV. Por exemplo, com um arquivo de entrada como este:
1;foo;bar;baz;x;y;z
2;foo;bar;baz;x;y;z
3;foo;bar;baz;x;y;z
Qual seria o comando (eventualmente usando cut
) para obter as duas últimas colunas, então eu recebo:
y;z
y;z
y;z
Na verdade, meu objetivo real é recuperar os 3 primeiros e os últimos 2 campos de cada linha, então fico:
1;foo;bar;y;z
2;foo;bar;y;z
3;foo;bar;y;z
Infelizmente, não consigo usar um comando como cut -d \; -f 1-3,10-11
(se houver 11 elementos na linha), porque o arquivo CSV não respeita o formato CSV real . De fato, alguns campos no meio das linhas são criptografados , e seu valor criptografado às vezes contém um ;
de caracteres (e, é claro, eles não são agrupados em "
). Em outras palavras, minhas falas podem parecer assim:
1;foo;bar;#@$"é&^l#;baz;x;y;z
2;foo;bar;#¤=é;)o'#;baz;x;y;z
3;foo;bar;#]]'~é{{#;baz;x;y;z
e como você pode ver, na segunda linha, há um caractere ;
adicional, então não posso usar aqui um comando como cut -d \; -f 1-3,7-8
, porque se retornará isso, o que está errado:
1;foo;bar;y;z
2;foo;bar;x;y (-> Wrong here, there is a shift)
3;foo;bar;y;z
Então, como posso usar o cut
para resolver meu problema?
Obrigado
ps: Eu sou especialmente apaixonado pelo comando cut
, então se você tem um comando que faz o que eu quero mas não é cut
, então está tudo bem também:)
Editar Parece importante notar que a máquina é bem antiga: uname -a
dê esta mensagem:
SunOS ###### 5.10 Generic_142900-05 sun4u sparc SUNW,Sun-Fire-V240
e alguns comandos podem não estar presentes (como rev
)
Aqui está uma solução de múltiplos comandos para recuperar os 3 primeiros e os 2 últimos campos usando apenas cut
, rev
(para reversão) e shell-builtins:
while read line
do
first=$(echo -n "$line" | cut -d ";" -f -3)
second=$(echo -n "$line" | rev | cut -d ";" -f -2 | rev)
echo "$first;$second"
done < my_file
Estas declarações também podem ser colocadas em uma única linha, é claro.
EDITAR:
Reuni algumas alternativas de uma linha para rev
(que omitem a impressão do final '\ n' ):
python: python -c "import sys; sys.stdout.write(raw_input()[::-1])
perl: perl -ne 'chomp;print scalar reverse;'
e há muito mais possibilidades de reverter uma string . Talvez alguns deles funcionem no seu sistema.
% cat a
1;foo;bar;#@$"é&^l#;baz;x;y;z
2;foo;bar;#¤=é;)o'#;baz;x;y;z
3;foo;bar;#]]'~é{{#;baz;x;y;z
% sed -r 's,^(([^;]+;){3}).*;([^;]+;[^;]+)$,,' < a
1;foo;bar;y;z
2;foo;bar;y;z
3;foo;bar;y;z
Tags text-processing ksh cut