alguns pequenos refinamentos:awk -v N=9 '{sep=""; for (i=N; i<=NF; i++) {printf("%s%s",sep,$i); sep=OFS}; printf("\n")}'
glenn jackman
Obrigado @glenn, isso é um pouco mais geral. De qualquer forma, eu definitivamente concordaria que seria melhor usar cutou perlpara isso. Use-o apenas se você realmente insistir em colocá-lo awk.
Amadan
1
@SiegeX: Não adiciona bytes NUL, deixa o FS no lugar entre cada campo vazio.
Dennis Williamson
1
Por favor, veja a resposta de @ Ascherer para elegância.
3
@veryhungrymike: Elegância é bom, mas prefiro estar correto. : p
Amadan
68
Quando você deseja fazer uma variedade de campos, awkrealmente não tem uma maneira direta de fazer isso. Eu recomendaria em cutvez disso:
cut -d' ' -f 9- ./infile
Editar
Adicionado delimitador de campo de espaço devido ao padrão ser uma guia. Obrigado a Glenn por apontar isso
Uma coisa sobre o corte é que ele usa um delimitador específico (tab por padrão), onde awk usa "espaço em branco". Com o corte, 2 tabulações consecutivas delimitam um campo vazio.
glenn jackman
1
Como @glennjackman apontou, o delimitador do awk é o "espaço em branco" (qualquer valor também). Portanto, definir o delimitador de corte para um espaço único não corresponderia ao comportamento também. infelizmente, o loop é o melhor que se pode fazer, então parece.
poncha de
Este não funciona corretamente. Experimente o comando find . | xargs ls -l | cut -d' ' -f 9-. Por alguma razão, os espaços duplos também são contados. Exemplo: lrwxrwxrwx 1 me me 21 Dec 12 00:00 ./file_a lrwxrwxrwx 1 me me 64 Dec 6 00:06 ./file_bresultará em./file_a 00:06 ./file_b
Marco Pashkov,
@MarcoPashkov, por favor, explique Este não funciona corretamente , especialmente considerando que você usa exatamente o mesmo código em seu pipeline. A propósito, você nunca
SiegeX
cortar não faz o trabalho aqui. Por exemplo, se sua entrada for "foo bar" (espaço único) para uma linha e "foo ___ bar" (ou seja, vários espaços, mas SO é muito inteligente para mostrá-lo) para outra, o cut irá processá-los de forma diferente.
UKMonkey
54
awk '{print substr($0, index($0,$9))}'
Editar : Observe que isso não funciona se qualquer campo antes do nono contiver o mesmo valor do nono.
@veryhungrymike: ... e não funciona se qualquer campo antes do nono contiver o mesmo valor do nono.
Amadan 01 de
6
Provavelmente por causa da frase clássica "espero que seu arquivo não tenha esse problema". É um total não-não em s / w de engenharia para o estado: "nós não vamos perder tempo inclusive para a entrada de por exemplo, valores negativos de verificação de erros, porque 'nós esperamos que o usuário será suficiente inteligente para não julgá-los fora, travando nossa ferramenta '". HAHAHA! Sempre adoro ouvir isso! (I como um bom senso de humor) Bem, como idiotas fazer existe, é dever do desenvolvedor para fazer o seu material à prova de idiotas ! Em vez de "esperar o bem do homem". Essa é uma atitude esperada de filósofos, não engenheiros s / w ... LOL
erro de sintaxe
3
Eu não estava dizendo para não verificar se há erros, mas se você sabe que não terá o problema, essa solução é adequada, como afirmei. Mas obrigado pelo downvote desnecessário de @syntaxerror. Esta solução funcionará para alguns, como os (atualmente) 19 votos positivos irão mostrar, mas se não funcionar, então não use para sua solução. Existem várias maneiras de resolver o problema do OP.
Ascherer
1
Se você estiver usando awk na linha de comando em seu trabalho diário, esta é definitivamente a solução que você deseja. Não é óbvio? A verificação de erros, etc, realmente não importa nesse caso, já que você está digitando e pode pegar esse tipo de coisa antes de pressionar enter (pessoalmente, não acho que awk deva ser usado para qualquer outra coisa, de qualquer maneira, é por isso que nós tenho perl, python, tcl e cerca de 100 outras linguagens de script melhores, mais rápidas e menos irritantes!) Claro, talvez eu esteja dando aos meus colegas desenvolvedores de software muito crédito e eles realmente precisam de verificação de erros, mesmo nas coisas que digitam em tempo real (??)
osirisgothra
1
Não que precisasse, pois está logo abaixo da resposta, mas eu adicionei @atti
Ascherer
11
sed -re 's,\s+, ,g' | cut -d ' ' -f 9-
Em vez de lidar com espaços em branco de largura variável, substitua todos os espaços em branco como um único espaço. Em seguida, use simples cutcom os campos de interesse.
Ele não usa awk, então não é pertinente, mas parecia apropriado dadas as outras respostas / comentários.
Você precisa adicionar a opção de linha de comando -lou adicionar \nà instrução de impressão.
glenn jackman
@glenn jackman: Possivelmente. Não requerido se for parte de outra mensagem, ou sendo atribuído a uma variável etc. No que diz respeito a "melhor", perl certamente fica melhor no pequeno. Pode parecer muito desarrumado no grande, admito.
bobbogo
Não me entenda mal, eu gosto do Perl. Eu amo o awk pelo que ele é.
glenn jackman
Meu dispositivo embutido não vem com Perl, mas tem awk.
Sepero de
Downvoting porque a questão perguntava como fazer isso no awk, e não no perl, ruby, java, python, bash.
Isso corta o que está antes do campo especificado nr., N, e imprime todo o resto da linha, incluindo o campo nr.N e mantém o espaçamento original (não reformata). Não importa se a string do campo aparece também em algum outro lugar da linha, que é o problema com a resposta de Ascherer.
Essa é uma boa ideia. Não funciona muito bem em um Mac atual usando o gawk típico, porque $ 0 entra em colapso. A correção é definir uma variável para $ 0 como a primeira etapa, como: '{s = $ 0; ... imprimir substr (s, índice (s, m) +1}
Usando cut em vez de awk e superando problemas para descobrir em qual coluna começar usando o comando -c character cut.
Aqui estou dizendo, dê-me todos, exceto os primeiros 49 caracteres da saída.
ls -l /some/path/*/* | cut -c 50-
O /*/*/no final do comando ls está dizendo mostre-me o que há nos subdiretórios também.
Você também pode puxar certos intervalos de caracteres ala (da página de manual de corte). Por exemplo, mostre os nomes e horários de login dos usuários atualmente conectados:
Respostas:
awk '{ s = ""; for (i = 9; i <= NF; i++) s = s $i " "; print s }'
fonte
awk -v N=9 '{sep=""; for (i=N; i<=NF; i++) {printf("%s%s",sep,$i); sep=OFS}; printf("\n")}'
cut
ouperl
para isso. Use-o apenas se você realmente insistir em colocá-loawk
.Quando você deseja fazer uma variedade de campos,
awk
realmente não tem uma maneira direta de fazer isso. Eu recomendaria emcut
vez disso:cut -d' ' -f 9- ./infile
Editar
Adicionado delimitador de campo de espaço devido ao padrão ser uma guia. Obrigado a Glenn por apontar isso
fonte
find . | xargs ls -l | cut -d' ' -f 9-
. Por alguma razão, os espaços duplos também são contados. Exemplo:lrwxrwxrwx 1 me me 21 Dec 12 00:00 ./file_a lrwxrwxrwx 1 me me 64 Dec 6 00:06 ./file_b
resultará em./file_a 00:06 ./file_b
awk '{print substr($0, index($0,$9))}'
Editar : Observe que isso não funciona se qualquer campo antes do nono contiver o mesmo valor do nono.
fonte
sed -re 's,\s+, ,g' | cut -d ' ' -f 9-
Em vez de lidar com espaços em branco de largura variável, substitua todos os espaços em branco como um único espaço. Em seguida, use simples
cut
com os campos de interesse.Ele não usa awk, então não é pertinente, mas parecia apropriado dadas as outras respostas / comentários.
fonte
ps faux |
uso. Nunca tenha medo de admitir que a ferramenta XYZ não seja a mais adequada.Geralmente perl substitui awk / sed / grep et. al., e é muito mais portátil (além de ser apenas um canivete melhor).
perl -lane 'print "@F[8..$#F]"'
Timtowtdi se aplica, é claro.
fonte
-l
ou adicionar\n
à instrução de impressão.awk -v m="\x01" -v N="3" '{$N=m$N ;print substr($0, index($0,m)+1)}'
Isso corta o que está antes do campo especificado nr., N, e imprime todo o resto da linha, incluindo o campo nr.N e mantém o espaçamento original (não reformata). Não importa se a string do campo aparece também em algum outro lugar da linha, que é o problema com a resposta de Ascherer.
Defina uma função:
fromField () { awk -v m="\x01" -v N="$1" '{$N=m$N; print substr($0,index($0,m)+1)}' }
E use-o assim:
$ echo " bat bi iru lau bost " | fromField 3 iru lau bost $ echo " bat bi iru lau bost " | fromField 2 bi iru lau bost
A saída mantém tudo, incluindo espaços finais Para N = 0 ela retorna a linha inteira, como está, e para n> NF a string vazia
fonte
Aqui está um exemplo de
ls -l
saída:Minha solução para imprimir qualquer coisa
$9
éawk '{print substr($0, 61, 50)}'
fonte
ruby -lane 'print $F[3..-1].join(" ")' file
fonte
Para exibir os 3 primeiros campos e imprimir os campos restantes, você pode usar:
awk '{s = ""; for (i=4; i<= NF; i++) s= s $i : "; print $1 $2 $3 s}' filename
onde $ 1 $ 2 $ 3 são os 3 primeiros campos.
fonte
function print_fields(field_num1, field_num2){ input_line = $0 j = 1; for (i=field_num1; i <= field_num2; i++){ $(j++) = $(i); } NF = field_num2 - field_num1 + 1; print $0 $0 = input_line }
fonte
Usando cut em vez de awk e superando problemas para descobrir em qual coluna começar usando o comando -c character cut.
Aqui estou dizendo, dê-me todos, exceto os primeiros 49 caracteres da saída.
O
/*/*/
no final do comando ls está dizendo mostre-me o que há nos subdiretórios também.Você também pode puxar certos intervalos de caracteres ala (da página de manual de corte). Por exemplo, mostre os nomes e horários de login dos usuários atualmente conectados:
fonte