awk '{print $NF}'
sed 's/[[:blank:]]*$//;s/.*[[:blank:]]//'
Isso ainda imprime uma linha vazia para cada linha em branco. Para evitar isso:
awk 'NF{print $NF}'
sed 's/[[:blank:]]*$//;s/.*[[:blank:]]//;/./!d'
suponha que, se houver um arquivo que contenha as seguintes linhas, se elas forem
12345 567 7878 66 er3 t45t y6y46y 4y6 y656y y5y 46y6 65y7 y66uyuy yy46y6y
A saída tem que se parecer com:
66 y6y46y y5y y66uyuyy y46y6y
Eu tentei o comando sed 's/.* //g'
filename e vários outros comandos sed
, mas não está funcionando.
Posso saber qual é o comando sed
exato?
awk '{print $NF}'
sed 's/[[:blank:]]*$//;s/.*[[:blank:]]//'
Isso ainda imprime uma linha vazia para cada linha em branco. Para evitar isso:
awk 'NF{print $NF}'
sed 's/[[:blank:]]*$//;s/.*[[:blank:]]//;/./!d'
A awk
variable $NF
é o último campo de cada registro ; você pode usá-lo para imprimir apenas os últimos campos do seu arquivo da seguinte forma:
awk '{print $NF}' file
Você pode tentar:
sed 's/.* //'
awk '{print $NF}'
Você está quase lá. Basta especificar a última palavra:
sed 's/^.* \([^ ][^ ]*\)//g'
O que faz:
(Editado para adicionar uma solução melhor. Obrigado Hildred!)
Você pode usar um padrão adequado de grep
em vez de sed
, por exemplo:
grep -o "[a-Z0-9]*$"
Neste exemplo, o [...]
contém intervalos de caracteres considerados apropriados para uma "palavra" (alfanuméricos, neste caso, outros símbolos podem ser adicionados, alguns dos quais devem ser escapados).
Se você qualifica palavra para significar qualquer sequência de 1 ou mais caracteres não-brancos então a resposta é definitivamente sim, e é muito simples também. Isso ocorre porque [[:blank:]]*
e [^[:blank:]]*
são complementos booleanos e - desde que todos os caracteres em uma cadeia estejam completos - [[:blank:]]*
U [^[:blank:]]*
pode descrever qualquer sequência possível da mesma maneira que .*
.
Se existir um caractere incompleto ou uma seqüência de byte inválida dentro de uma string, não é possível descrevê-lo com sucesso - como às vezes pode ocorrer quando se interpreta uma string na codificação incorreta. Para garantir um caractere completo por byte em qualquer string, a localidade C pode ser forçada como:
LC_ALL=C sed ...
... o que evitaria quaisquer problemas que descrevessem a string da cabeça à cauda com um padrão all-inclusive, como .*
ou ([ ]*[^ ]*)*
Um padrão totalmente complementar pode se repetir quantas vezes for necessário, da esquerda para a direita, o comprimento de qualquer corda para pousar na última ocorrência possível, sem qualquer quebra no padrão. Isto é, definitivamente, linguagem regular.
sed 's/\(\([^[:blank:]]*\)[[:blank:]]*\)*//'
sed -E 's/(([^[:blank:]]*)[[:blank:]]*)*//'
Ambas as versões ainda imprimirão linhas em branco, e isso ocorre porque a estrela Kleene *
corresponde a zero ou mais ocorrências de um padrão. Primeiramente, ele corresponde a zero ou mais caracteres não em branco, depois a zero ou mais caracteres em branco e, em seguida, a zero ou mais ocorrências das correspondências agrupadas até que corresponda à string em sua totalidade.
Tendo combinado tudo isso, a mágica acontece na substituição - as referências retornadas pelos grupos e
são as últimas ocorrências de cada uma. Assim, quando a substituição é feita, toda a string é substituída apenas pela última ocorrência em uma linha de zero ou mais caracteres não em branco - ou o subgrupo
.
É claro que isso funciona para qualquer seqüência possível - até mesmo uma vazia - o que significa que os dois formulários imprimirão caracteres de nova linha para linhas que contenham apenas caracteres em branco ou nenhum. Para lidar com isso, há algumas coisas que você pode fazer, mas primeiro vamos tornar a classe de caracteres um pouco mais fácil de digitar:
b='[:blank:]'
Agora, para imprimir apenas se uma linha contiver um ou mais caracteres não em branco, você pode fazer:
sed -n "s/\(\([^$b]*\)[$b]*\)*//;/./p"
sed -En "/[^$b]/s/(([^$b]*)[$b]*)*//p"
Qualquer um dos formulários funcionará com um dos métodos, desde que a sintaxe esteja correta.
A chave -n
desabilita a impressão automática do espaço padrão, e a% bandeira p
aos comandos s///
ubstitution ou /
address /
imprime seus resultados somente se for bem-sucedida.
Essa mesma lógica pode ser aplicada para obter qualquer {num}
th ocorrência, assim como:
sed -n "s/\([$b]*\([^$b]\{1,\}\)\)\{num\}.*//p"
sed -En "s/([$b]*([^$b]+)){num}.*//p"
... onde o num
em ambos os regexps pode ser substituído por um número para imprimir somente a {num}
th ocorrência especificada de uma seqüência de caracteres não em branco. Uma forma ligeiramente diferente é usada aqui para garantir que a contagem não seja distorcida para espaços iniciais em uma string.
Observe que a opção -E
ERE para sed
é suportada nas versões BSD e GNU, embora não seja ainda sintaxe padrão POSIX.
Sim. O seguinte comando sed primeiro remove todos os espaços em branco finais ( s/ *$//
) e, em seguida, tudo até e incluindo o último espaço em branco ( s/.* //
). Provavelmente vale a pena substituir o espaço em branco literal por [[:blank:]]
para capturar guias e outros caracteres semelhantes a espaço.
$ echo " aaa bbb cc " | sed -e 's/ *$//' -e 's/.* //'
cc
$ echo " aaa bbb cc" | sed -e 's/ *$//' -e 's/.* //'
cc
$ echo "aaa bbb cc " | sed -e 's/ *$//' -e 's/.* //'
cc
$ echo "aaa bbb cc" | sed -e 's/ *$//' -e 's/.* //'
cc
$ echo " cc " | sed -e 's/ *$//' -e 's/.* //'
cc
$ echo "cc" | sed -e 's/ *$//' -e 's/.* //'
cc
cat file_name | rev | cut -f1 -d ' ' | rev
Tags text-processing awk sed