mon fichier texte ressemble à ceci:
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
maintenant je veux supprimer Liquid penetration 95% mass (m)
de mes lignes pour obtenir uniquement les valeurs. Comment dois-je procéder?
grep -o '[^[:space:]]\+$' file
\S+$
avec-E
ou-P
.) Ce type de solution n'est donc pas intrinsèquement lent. Mais je n'arrive toujours pas à me rapprocher de lacut
méthode d' αғsнιη , qui a également gagné votre référence .Réponses:
S'il n'y a qu'un seul
=
signe, vous pouvez tout supprimer avant et y compris=
comme ceci:Si vous souhaitez modifier le fichier d'origine, utilisez l'
-i
option après le test:Remarques
-r
utiliser ERE afin que nous n'ayons pas à nous échapper(
et)
s/old/new
remplacerold
parnew
.*
un nombre quelconque de caractères(things)
enregistrerthings
pour plus tard avec référence arrière\1
,\2
etc.la source
s/^.*= //
fonctionnerait tout aussi bien, car la valeur correcte est à la fin de la ligne.\1
etc. a une certaine valeur pour les personnes qui atterrir sur cette question lors de la recherche, qui n'ont pas un problème aussi simpleC'est un travail pour
awk
; en supposant que les valeurs n'apparaissent que dans le dernier champ (selon votre exemple):NF
est uneawk
variable, s'étend au nombre de champs dans un enregistrement (ligne), donc$NF
(notez le$
devant) contient la valeur du dernier champ.Exemple:
la source
J'ai décidé de comparer les différentes solutions, listées ici. À cet effet, j'ai créé un gros fichier, basé sur le contenu fourni par l'OP:
J'ai créé un fichier simple, nommé
input.file
:Ensuite, j'ai exécuté cette boucle:
La fenêtre du terminal a été bloquée. J'ai exécuté
killall tee
depuis un autre terminal. J'ai ensuite examiné le contenu du fichier par les commandes:less input.file
etcat input.file
. Ça avait l'air bien, sauf la dernière ligne. J'ai donc supprimé la dernière ligne et créé une copie de sauvegarde:cp input.file{,.copy}
(à cause des commandes qui utilisent l' option inplace ).Le nombre final de lignes dans le fichier
input.file
est de 2 192 473 . J'ai obtenu ce numéro par la commandewc
:Voici le résultat de la comparaison:
grep -o '[^[:space:]]\+$'
sed -ri 's/.* = (.*)/\1/'
Alternativement, si nous redirigeons la sortie vers un nouveau fichier, la commande est plus rapide:
gawk '{gsub(".*= ", "");print}'
rev | cut -d' ' -f1 | rev
grep -oP '.*= \K.*'
sed 's/.*= //'
(respectivement, l'-i
option rend la commande plusieurs fois plus lente)perl -pe 's/.*= //'
(l'-i
option ne produit pas de grande différence de productivité ici)awk '{print $NF}'
cut -c 35-
cut -d= -f2
La source de l'idée.
la source
cut -d= -f2
solution gagne. hahawc -l
produit trois nombres? Lorsqu'aucune autre option n'est transmise, l'-l
option doit supprimer tout sauf le nombre de lignes.wc
réellement affiché ces espaces? Existe-t-il des paramètres régionaux pour lesquels il fera cela?) Merci pour la mise à jour!wc
une fois de plus. Je ne sais pas où étaient mes esprits tôt aujourd'hui, mais je ne pouvais vraiment pas les comprendre. Donc, en effet, les espaces étaient des séparateurs de groupes de chiffres , etwc
ne les ajoutent pas :)Avec
grep
et-P
pour avoirPCRE
(interpréter le motif en tant que P erl- C ompatible R REGULIERS E xpression) et-o
d'imprimer identifié motif seul. La\K
notification ignorera la partie correspondante avant elle-même.Ou vous pouvez utiliser la
cut
commande à la place.la source
cut
méthode de cette réponse a également été clairement gagnante dans un test de référence plus petit que j'ai exécuté qui a testé moins de méthodes mais a utilisé un fichier d'entrée plus volumineux. C'était bien plus de dix fois plus rapide que la variante rapide de la méthode que j'aime personnellement (et que ma réponse concerne principalement).Étant donné que le préfixe de ligne a toujours la même longueur (34 caractères), vous pouvez utiliser
cut
:la source
Inversez le contenu du fichier avec
rev
, canalisez la sortiecut
avec un espace comme délimiteur et 1 comme champ cible, puis inversez-le à nouveau pour obtenir le numéro d'origine:la source
C'est simple, court et facile à écrire, à comprendre et à vérifier, et je l'aime personnellement:
grep
dans Ubuntu , lorsqu'il est invoqué avec-E
ou-P
, prend le raccourci\s
pour signifier un caractère d'espace blanc (en pratique, généralement un espace ou une tabulation) et\S
pour signifier tout ce qui n'en est pas un. En utilisant le quantificateur+
et l'ancre de fin de ligne$
, le motif\S+$
correspond à un ou plusieurs espaces non à la fin d'une ligne . Vous pouvez utiliser à la-P
place de-E
; dans ce cas, la signification est la même, mais un moteur d'expressions régulières différent est utilisé, de sorte qu'elles peuvent avoir des caractéristiques de performances différentes .C'est équivalent à la solution commentée d'Avinash Raj (juste avec une syntaxe plus simple et plus compacte):
Ces approches ne fonctionneront pas s'il peut y avoir des espaces de fin après le nombre. Ils peuvent être modifiés comme ils le font, mais je ne vois aucun intérêt à y entrer ici. Bien qu'il soit parfois instructif de généraliser une solution pour travailler dans plus de cas, il n'est pas pratique de le faire presque aussi souvent que les gens ont tendance à le supposer, car on n'a généralement aucun moyen de savoir de quelles manières incompatibles différentes le problème pourrait finalement avoir à résoudre. être généralisé.
La performance est parfois une considération importante. Cette question ne stipule pas que l'entrée est très grande, et il est probable que chaque méthode qui a été publiée ici est assez rapide. Cependant, si la vitesse est souhaitée, voici un petit point de repère sur un fichier d'entrée de dix millions de lignes:
Je l'ai exécuté deux fois au cas où l'ordre importait (comme c'est parfois le cas pour les tâches lourdes d'E / S) et parce que je n'avais pas de machine disponible qui ne faisait pas d'autres choses en arrière-plan qui pourraient fausser les résultats. De ces résultats, je conclus ce qui suit, au moins provisoirement et pour les fichiers d'entrée de la taille que j'ai utilisée:
Hou la la! Passer
-P
(pour utiliser PCRE ) plutôt que-G
(par défaut quand aucun dialecte n'est spécifié) ou-E
rendugrep
plus rapide de plus d'un ordre de grandeur. Ainsi, pour les fichiers volumineux, il peut être préférable d'utiliser cette commande que celle illustrée ci-dessus:SENSATIONNEL!! La
cut
méthode dans la réponse de αғsнιη , est sur un ordre de grandeur plus rapide que même la version plus rapide de mon chemin! C'était également le gagnant du benchmark pa4080 , qui couvrait plus de méthodes que cela mais avec une entrée plus petite - et c'est pourquoi je l'ai choisi, parmi toutes les autres méthodes, à inclure dans mon test. Si les performances sont importantes ou si les fichiers sont énormes, je pense que la méthode de αғsнιη devrait être utilisée.cut -d= -f2 file
cut
Cela sert également à rappeler que le simple
cut
et lespaste
utilitaires ne doivent pas être oubliés , et devraient peut-être être préférés le cas échéant, même s'il existe des outils plus sophistiqués commegrep
celui-ci sont souvent proposés en tant que solutions de première ligne (et que je suis personnellement plus habitué à utiliser).la source
perl
- s ubstitute le modèle/.*= /
avec une chaîne vide//
:De
perl --help
:sed
- remplacez le motif par une chaîne vide:ou (mais plus lent que ci-dessus) :
gawk
- remplacez le motif".*= "
par une chaîne vide""
:De
man gawk
:la source