Respostas:
A -Fopção precisa de um argumento: -F,por exemplo.
O final do awkscript deve ser separado por um (caractere de espaço) com o restante dos parâmetros.
Se o separador de campos for ,e você deseja mantê-lo, e se o número de colunas for constante e menor que ou igual a 11, tente isso:
awk -F, '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}' OFS=, "$file"
command file > newfile && mv newfile file. Dito isto, a versão mais recente do GNU awkpara apoiar este: gawk -i inplace '{blah blah}' file.
mv newfile filevocê pode usar cat newfile > file ; rm -f newfile- isso preserva o inode e as permissões de file.
mktempvez de codificar, nomes de arquivos temporários em scripts. por exemplotf=$(mktemp) ; command file > "$tf" ; cat "$tf" > file ; rm -f "$tf"
Solução mais curta seria
awk -F',+' -v OFS=, '{$(NF+1)=$7; $7=""; $0=$0; $1=$1}1' file
Não tenho certeza se ,+funcionará em todas as awkversões, mas funciona pelo menos no GNU awk, também com o -cmodo de compatibilidade.
Explicação:
$(NF+1)=$7: primeiro, adicionamos o sétimo campo ao final da linha (pode ser $12=$7neste caso)$7="": na próxima etapa, o 7º campo é apagado (mas os delimitadores circundantes permanecem)$0=$0) tratando várias vírgulas como separador de campo (isso é feito via -F',+', aqui +significa uma ou mais vezes) e também reorganizar o registro atual via $1=$1para forçar a reconstrução da linha usando o campo de saída definido anteriormente separador (definido por uma opção -v OFS=,)1Exemplo de entrada:
1,2,3,4,5,6,7,8,9,10,11
resultado
1,2,3,4,5,6,8,9,10,11,7
,+deve funcionar.
all,ball,call,,,fall→ all,ball,call,fall). (2) $(NF+1)=$7é uma abordagem inteligente. IMHO, $0 = $0 OFS $7é um pouco mais claro, apenas alguns caracteres a mais, e parece fazer a mesma coisa. Você consegue pensar em uma situação em que $0 = $0 OFS $7não faça o mesmo que o seu código?
$0=$0 OFS $7provavelmente é idêntico a $(NF+1)=$7, mas apenas com o restante do código inalterado, não em geral.
Se estiver imprimindo com OFS=, portanto, sem separador entre os campos, você pode simplesmente salvar o valor de $7em uma variável, definido $7como vazio e imprimir a linha e a variável diretamente. Você não precisa especificar todos os campos:
$ cat file
1,2,3,4,5,6,7,8
$ awk -F, -vOFS= '{k=$7; $7=""; print $0,k}' file
12345687
Você provavelmente quer dizer:
awk -F, -v OFS='' '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}' "$file"
awknunca vê as aspas simples OFS='', certo? Você também pode digitar OFS=; é exatamente o mesmo.
Você não diz especificamente que você queria usar awk, e você me disse que queria usar a edição no local, como fornecido pelo sed -i, então aqui é uma sed -ivariante. Geralmente awké melhor trabalhar com colunas, mas esse é um caso em que eu prefiro sed, porque naturalmente lida com números arbitrários de colunas.
MOVECOL=7
N=$((MOVECOL-1))
sed -r -e "s/^(([^,]*,){$N})([^,]*),(.*)/\1\4,\3/" -i test.csv
Explicação:
-r seleciona regexps estendidos, para evitar muitas barras invertidasÉ claro que isso não funcionará com arquivos que ocultam vírgulas entre aspas (ou pior, escapam), mas o awk também não lidará com isso sem algumas acrobacias sérias. Se você tiver esse problema, seria melhor usar o perlmódulo Text:CSVou o pythonmódulo csv.
Algumas awkvariantes (supondo que seu arquivo esteja dentro da variável $file)
Aqui você pode pedalar por toda a cor, imprimir com o separador de campos (OFS) e imprimir o terminador de registro (ORS) no final da linha.
awk -F',' -v OFS=, \
'{for(i=1;i<=NF;i++) if (i!=7) printf "%s",$i OFS; \
printf "%s",$7;printf ORS}' "$file"Aqui com o uso de um regex e a gensub()função
gawk -F',+' -v OFS=, '{$0=gensub(/\s*\S+/,"",7) OFS $7}1' "$file"
matando o 7º campo e imprimindo no final da linha.
$0 é todo o registro $né o nono registro NF é o número de campos da linha atual OFS o separador arquivado de saídaORS o terminador do registro de saída1é o truque a ser dito para ativar truee imprimir o padrão ( $0).Atualizar ...
Quase esqueço que é possível mudar todas as colunas após a 7ª .
awk -F',' -v OFS=, '{tmp=$7; for(i=7;i<=NF;i++) $i=$(i+1); $NF=tmp}1 ' "$file"
OFS $7seria mais robusto que "," $7. (2) Eu acredito que ", " $7é errado, na medida em que a questão indica que o OP não quer espaços após as vírgulas. (E, se os dados de entrada tivessem espaços após as vírgulas, $7eles já começariam com um espaço e você incluiria um adicional.)
OFS $7, não só mais robusta, mas ainda mais geral ( "pressa deixa resíduos" )
^indica a parte específica do comando onde o erro foi encontrado.