Eu tenho um arquivo parecido com este:
AE United Arab Emirates
AG Antigua & Barbuda
AN Netherlands Antilles
AS American Samoa
BA Bosnia and Herzegovina
BF Burkina Faso
BN Brunei Darussalam
E eu gostaria de inverter a ordem, imprimindo primeiro tudo, exceto $ 1 e depois $ 1:
United Arab Emirates AE
Como posso fazer o truque "tudo exceto o campo 1"?
Respostas:
A atribuição
$1
funciona, mas deixará um espaço inicial:awk '{first = $1; $1 = ""; print $0, first; }'
Você também pode encontrar o número de colunas
NF
e usá-lo em um loop.fonte
awk {'first = $1; $1=""; print $0'}|sed 's/^ //g'
$1=""
deixa um espaço como Ben Jackson mencionou, então use umfor
loop:Portanto, se sua string era "um, dois, três", a saída será:
dois
tres
Se quiser o resultado em uma linha, você pode fazer o seguinte:
Isso lhe dará: "dois três"
fonte
awk '{for(i=2;i<=NF;i++){ printf("%s",( (i>2) ? OFS : "" ) $i) } ; print ;}'
que: imprime os campos 2 em NF, adiciona o separador de campo de saída conforme necessário (ou seja, exceto antes de $ 2). A última impressão adiciona uma nova linha final para encerrar a impressão da linha atual. Esse funcionará se você alterar FS / OFS (ou seja, não será sempre "espaço")Use o
cut
comando com a--complement
opção:fonte
echo a b c | cut -d' ' -f 2-
é uma alternativaTalvez a maneira mais concisa:
Explicação:
$(NF+1)=$1
: Gerador de um "novo" último campo.$1=""
: Defina o primeiro campo original como nulosub(FS,"")
: Após as duas primeiras ações,{$(NF+1)=$1;$1=""}
elimine o primeiro separador de campo usando sub. A impressão final está implícita.fonte
Remova o primeiro campo e o separador e imprima o resultado (
7
é um valor diferente de zero, portanto imprimindo $ 0).fonte
1
? Gostaria de saber o uso desse padrão e queria entender isso. obrigado!Definir o primeiro campo como
""
deixa uma única cópia deOFS
no início de$0
. Supondo queOFS
seja apenas um único caractere (por padrão, é um único espaço), podemos removê-lo comsubstr($0, 2)
. Em seguida, acrescentamos a cópia salva de$1
.fonte
Se você está aberto a uma solução Perl ...
é uma solução simples com um separador de entrada / saída de um espaço, que produz:
Este próximo é um pouco mais complexo
e assume que o separador de entrada / saída tem dois espaços:
Estas opções de linha de comando são usadas:
-n
fazer um loop em cada linha do arquivo de entrada, não imprimir automaticamente todas as linhas-l
remove novas linhas antes do processamento e as adiciona de volta depois-a
modo autosplit - divide as linhas de entrada no array @F. O padrão é divisão em espaços em branco-F
modificador autosplit, neste exemplo divide-se em '' (dois espaços)-e
execute o seguinte código perl@F
é a matriz de palavras em cada linha, indexada começando com 0$#F
é o número de palavras em@F
@F[1..$#F]
é uma fatia da matriz do elemento 1 até o último elemento@F[1..$#F,0]
é uma fatia da matriz do elemento 1 até o último elemento mais o elemento 0fonte
O separador de campo no gawk (pelo menos) pode ser uma string, bem como um caractere (também pode ser um regex). Se seus dados forem consistentes, isso funcionará:
São dois espaços entre as aspas duplas.
fonte
awk '{ tmp = $1; sub(/^[^ ]+ +/, ""); print $0, tmp }'
fonte
Vamos mover todos os registros para o próximo e definir o último como o primeiro:
Explicação
a=$1
salve o primeiro valor em uma variável temporária.for (i=2; i<=NF; i++) $(i-1)=$i
salve o valor do campo enésimo no campo (N-1).$NF=a
salve o primeiro valor ($1
) no último campo.{}1
verdadeira condição para fazerawk
executar a ação padrão:{print $0}
.Dessa forma, se você tiver outro separador de campo, o resultado também será bom:
fonte
Uma primeira tentativa parece funcionar para o seu caso particular.
fonte
Opção 1
Existe uma solução que funciona com algumas versões do awk:
Explicação:
Resultado:
No entanto, isso pode falhar com versões anteriores do awk.
opção 2
Isso é:
Observe que o que precisa ser apagado é o OFS, não o FS. A linha é recalculada quando o campo $ 1 é atribuído. Isso muda todas as execuções de FS para um OFS.
Mas mesmo essa opção ainda falha com vários delimitadores, como é claramente mostrado ao alterar o OFS:
Essa linha produzirá:
Isso revela que as execuções do FS estão sendo alteradas para um OFS.
A única maneira de evitar isso é evitar o recálculo do campo.
Uma função que pode evitar o recálculo é sub.
O primeiro campo pode ser capturado e removido de $ 0 com sub e, em seguida, ambos reimpressos.
Opção 3
Mesmo se mudarmos o FS, o OFS e / ou adicionarmos mais delimitadores, funciona.
Se o arquivo de entrada for alterado para:
E o comando muda para:
A saída será (ainda preservando os delimitadores):
O comando pode ser expandido para vários campos, mas apenas com awks modernos e com a opção --re-interval ativa. Este comando no arquivo original:
Irá produzir isto:
fonte
Se você estiver aberto a outra solução Perl:
fonte
Existe uma opção sed também ...
Explicado ...
Mais detalhadamente explicado ...
fonte
Ainda outra maneira ...
... isso reúne os campos 2 a NF com o FS e produz uma linha por linha de entrada
Eu uso isso com o git para ver quais arquivos foram modificados em meu diretório de trabalho:
fonte
Outra maneira fácil de usar o comando cat
fonte