meu arquivo de texto fica assim:
Liquid penetration 95% mass (m) = 0.000205348
Liquid penetration 95% mass (m) = 0.000265725
Liquid penetration 95% mass (m) = 0.000322823
Liquid penetration 95% mass (m) = 0.000376445
Liquid penetration 95% mass (m) = 0.000425341
agora eu quero excluir Liquid penetration 95% mass (m)
das minhas linhas para obter apenas os valores. Como devo fazer isso?
grep -o '[^[:space:]]\+$' file
\S+$
com um-E
ou outro-P
.) Portanto, esse tipo de solução não é inerentemente lento. Mas ainda não consigo chegar nem perto docut
método de αғsнιη , que também ganhou sua referência .Respostas:
Se houver apenas um
=
sinal, você poderá excluir tudo antes e incluir=
assim:Se você deseja alterar o arquivo original, use a
-i
opção após o teste:Notas
-r
use ERE para que não tenhamos que escapar(
e)
s/old/new
substituaold
pornew
.*
qualquer número de caracteres(things)
salvarthings
a referência anterior mais tarde, com\1
,\2
, etc.fonte
s/^.*= //
funcionaria igualmente bem, pois o valor correto está no final da linha.\1
etc tenha algum valor para as pessoas que terra sobre esta questão durante a pesquisa, que não têm um problema tão simplesEste é um trabalho para
awk
; supondo que os valores ocorram apenas no último campo (conforme seu exemplo):NF
é umaawk
variável, se expande para o número de campos em um registro (linha), portanto$NF
(observe a$
frente) contém o valor do último campo.Exemplo:
fonte
Decidi comparar as diferentes soluções, listadas aqui. Para esse fim, criei um arquivo grande, com base no conteúdo fornecido pelo OP:
Eu criei um arquivo simples, chamado
input.file
:Então eu executei este loop:
A janela do terminal foi bloqueada. Eu executei
killall tee
de outro terminal. Depois examinei o conteúdo do arquivo pelos comandos:less input.file
ecat input.file
. Parecia bom, exceto a última linha. Então, removi a última linha e criei uma cópia de backup:cp input.file{,.copy}
(por causa dos comandos que usam a opção inplace ).A contagem final das linhas no arquivo
input.file
é 2 192 473 . Eu recebi esse número pelo comandowc
:Aqui está o resultado da comparação:
grep -o '[^[:space:]]\+$'
sed -ri 's/.* = (.*)/\1/'
Como alternativa, se redirecionarmos a saída para um novo arquivo, o comando será mais rápido:
gawk '{gsub(".*= ", "");print}'
rev | cut -d' ' -f1 | rev
grep -oP '.*= \K.*'
sed 's/.*= //'
(respectivamente, a-i
opção torna o comando algumas vezes mais lento)perl -pe 's/.*= //'
(a-i
opção não produz grande diferença na produtividade aqui)awk '{print $NF}'
cut -c 35-
cut -d= -f2
A fonte da ideia.
fonte
cut -d= -f2
solução vence. hahawc -l
gera três números? Quando nenhuma outra opção é aprovada, a-l
opção deve suprimir tudo, exceto a contagem de linhas.wc
Na verdade, havia exibido esses espaços? Existem configurações de localidade para as quais ele fará isso?) Obrigado pela atualização!wc
uma vez. Não sei onde estava minha mente hoje, mas realmente não conseguia entendê-las. Então, na verdade, os espaços foram separadores de grupos de dígitos , ewc
não adicioná-los :)Com
grep
eo-P
por terPCRE
(interpretar o padrão como um P erl- C ompatible R egular E xpression) e o-o
padrão de impressão combinados sozinho. A\K
notificação ignorará a parte correspondente que vem antes de si mesma.Ou você pode usar o
cut
comando.fonte
cut
método nesta resposta também foi o vencedor em um benchmark menor que executei que testou menos métodos, mas usou um arquivo de entrada maior. Foi bem mais de dez vezes mais rápido que a variante rápida do método que eu pessoalmente gosto (e que minha resposta é principalmente sobre).Como o prefixo da linha sempre tem o mesmo comprimento (34 caracteres), você pode usar
cut
:fonte
Inverta o conteúdo do arquivo com
rev
, canalize a saídacut
com o espaço como delimitador e 1 como o campo de destino e, em seguida, inverta-o novamente para obter o número original:fonte
É simples, curto e fácil de escrever, entender e verificar, e eu pessoalmente gosto:
grep
no Ubuntu , quando chamado com-E
ou-P
, usa a abreviação\s
para significar um caractere de espaço em branco (na prática geralmente um espaço ou guia) e\S
para significar qualquer coisa que não seja um. Usando o quantificador+
e a âncora de fim de linha$
, o padrão\S+$
corresponde a um ou mais não espaços em branco no final de uma linha . Você pode usar em-P
vez de-E
; o significado nesse caso é o mesmo, mas um mecanismo diferente de expressões regulares é usado; portanto, eles podem ter características de desempenho diferentes .Isso é equivalente à solução comentada de Avinash Raj (apenas com uma sintaxe mais fácil e mais compacta):
Essas abordagens não funcionarão se houver espaço em branco após o número. Eles podem ser modificados, mas não vejo sentido em entrar aqui. Embora às vezes seja instrutivo generalizar uma solução para funcionar em mais casos, não é prático fazê-lo com a frequência que as pessoas supõem, porque geralmente não há como saber de que maneiras diferentes e incompatíveis o problema pode precisar. ser generalizado.
Às vezes, o desempenho é uma consideração importante. Esta pergunta não estipula que a entrada seja muito grande e é provável que todos os métodos publicados aqui sejam rápidos o suficiente. No entanto, caso a velocidade seja desejada, aqui está uma pequena referência em um arquivo de entrada de dez milhões de linhas:
Executei-o duas vezes, caso a ordem importasse (como às vezes é importante para tarefas pesadas de E / S) e porque não havia uma máquina disponível que não estivesse fazendo outras coisas em segundo plano que poderiam distorcer os resultados. A partir desses resultados, concluo o seguinte, pelo menos provisoriamente e para arquivos de entrada do tamanho que usei:
Uau! Passando
-P
(para usar PCRE ) em vez de-G
(o padrão quando nenhum dialeto é especificado) ou-E
tornadogrep
mais rápido em uma ordem de magnitude. Portanto, para arquivos grandes, pode ser melhor usar este comando do que o mostrado acima:UAU!! O
cut
método de resposta de αғsнιη , é mais de uma ordem de grandeza mais rápido do que até mesmo a versão mais rápida do meu caminho! Também foi o vencedor no benchmark do pa4080 , que abrangeu mais métodos do que isso, mas com menor contribuição - e é por isso que eu o escolhi, dentre todos os outros métodos, para incluir no meu teste. Se o desempenho é importante ou os arquivos são enormes, acho que o método de αғsнιη deve ser usado.cut -d= -f2 file
cut
Isso também serve como um lembrete de que o simples
cut
e ospaste
utilitários não devem ser esquecidos , e talvez devam ser preferidos quando aplicável, embora existam ferramentas mais sofisticadas comogrep
essas que são frequentemente oferecidas como soluções de primeira linha (e que eu pessoalmente estou mais acostumado para usar).fonte
perl
- s ubstitute o padrão/.*= /
com string vazia//
:De
perl --help
:sed
- substitua o padrão por uma string vazia:ou (mas mais lento que o acima) :
gawk
- substitua o padrão".*= "
por uma string vazia""
:De
man gawk
:fonte