supposons, s'il y a un fichier composé des lignes suivantes, si elles sont
12345 567 7878 66 er3 t45t y6y46y 4y6 y656y y5y 46y6 65y7 y66uyuy yy46y6y
La sortie doit ressembler à:
66 y6y46y y5y y66uyuyy y46y6y
J'ai essayé la commande sed 's/.* //g'
filename et plusieurs autres sed
commandes, mais cela ne fonctionne pas.
Puis-je savoir quelle est la sed
commande exacte ?
text-processing
sed
awk
Rajeev Nukala
la source
la source
sed
?Réponses:
Cela imprimerait toujours une ligne vide pour chaque ligne vierge. Pour l'éviter:
la source
sed -n 's/.*[[:blank:]]\+\([^[:blank:]]\+\)[[:blank:]]*$/\1/p'
..*
à la queue, probablement - vous excluez tout sauf les blancs de toute façon avec.*[^[:blank:]]
.La
awk
variable$NF
est le dernier champ de chaque enregistrement ; vous pouvez l'utiliser pour imprimer uniquement les derniers champs de votre fichier comme ceci:la source
Tu peux essayer :
sed 's/.* //'
awk '{print $NF}'
la source
Tu y es presque. Précisez simplement le dernier mot:
Ce qu'il fait:
(Modifié pour ajouter une meilleure solution. Merci Hildred!)
la source
sed -r 's/.* ([^ ]+)/\1/g'
si les expressions régulières étendues sont autorisées, ce qui est généralement le cas.sed 's/.* //'
Vous pouvez utiliser un modèle adéquat de
grep
au lieu desed
, par exemple:Dans cet exemple, le
[...]
contient des plages de caractères considérées comme appropriées pour un "mot" (alphanumériques dans ce cas, d'autres symboles pourraient être ajoutés, dont certains doivent être échappés).la source
a-Z
car une plage n'a pas beaucoup de sens, même dans les environnements locaux basés sur ASCII. Notez qu'il-o
s'agit d'une extension GNU.Si vous qualifiez un mot pour signifier n'importe quelle séquence de 1 ou plusieurs caractères non vides, la réponse est certainement oui, et cela se fait très simplement également. En effet,
[[:blank:]]*
et[^[:blank:]]*
sont des compléments booléens et - à condition que tous les caractères d'une chaîne soient complets -[[:blank:]]*
U[^[:blank:]]*
peut décrire n'importe quelle chaîne possible de la même manière.*
.Si un caractère incomplet ou une séquence d'octets non valide existe dans une chaîne, ni l'un ni l'autre ne peut le décrire correctement, comme cela peut parfois se produire lors de l'interprétation d'une chaîne dans le mauvais codage. Pour garantir un caractère complet par octet dans n'importe quelle chaîne, les paramètres régionaux C peuvent être forcés comme:
... ce qui éviterait tout problème de description de la chaîne de la tête à la queue avec un modèle tout compris tel que
.*
ou([ ]*[^ ]*)*
Un modèle entièrement complémentaire peut répéter autant de fois que nécessaire de gauche à droite la longueur de n'importe quelle chaîne pour atterrir sur la dernière occurrence possible sans interruption du modèle. C'est, définitivement, un langage régulier.
BRE:
AVANT:
Ces deux versions imprimeront toujours des lignes vierges, et c'est parce que l'
*
étoile Kleene correspond à zéro ou plusieurs occurrences d'un motif. Il correspond d'abord à zéro ou plusieurs caractères non vides, puis à zéro ou plusieurs caractères vides, puis à zéro ou plusieurs occurrences des correspondances groupées jusqu'à ce qu'il corresponde à la chaîne dans son intégralité.Ayant fait correspondre tout cela, la magie opère dans le remplacement - les références retournées par les groupes
\1
et\2
sont les dernières occurrences de chacun. Ainsi, lorsque le remplacement est effectué, toute la chaîne est remplacée par la dernière occurrence sur une ligne de zéro ou plusieurs caractères non vides - ou le sous-groupe\2
.Bien sûr, cela fonctionne pour toute chaîne possible - même une chaîne vide - ce qui signifie que les deux formulaires imprimeront des caractères de nouvelle ligne pour les lignes qui ne contiennent que des caractères vierges ou pas du tout. Pour gérer cela, vous pouvez faire quelques choses, mais rendons d'abord la classe de caractères un peu plus facile à taper:
Maintenant, pour imprimer uniquement si une ligne contient un ou plusieurs caractères non vides, vous pouvez faire:
BRE:
AVANT:
L'une ou l'autre forme fonctionnera avec l'une ou l'autre méthode - tant que la syntaxe est correcte.
Le
-n
commutateur désactive l'impression automatique de l'espace de motif et l'p
indicateur de l's///
ubstitution ou des commandes d'/
adresse/
imprime ses résultats uniquement en cas de succès.Cette même logique peut également être appliquée pour obtenir n'importe quelle
{num}
occurrence, comme:BRE:
AVANT:
... où les
num
deux expressions rationnelles peuvent être remplacées par un nombre pour imprimer uniquement l'{num}
occurrence spécifiée d'une séquence de caractères non vides. Une forme légèrement différente est utilisée ici pour garantir que le nombre n'est pas faussé pour l'espace de début dans une chaîne.Notez que le
-E
commutateur EREsed
est pris en charge dans les versions BSD et GNU, bien qu'il ne soit pas encore la syntaxe standard POSIX.la source
sed
implémentations traditionnelles (comme Solaris / usr / bin / sed) et qu'il sera plus cher que l'approche la plus simple (épuise la mémoire avec des lignes d'entrée de plus de 25 caractères avec lesed_su3
du toolchest par exemple Heirloom). Donc, bien que j'aime la réponse, je ne recommanderais pas cette approche.s/.* \([^[:blank:]]\{1,\}\).*/\1/
c'est beaucoup mieux, mais c'est plus difficile lorsque plusieurs lignes sont impliquées. L'autre jour, cependant, j'ai découvert que cela's/\(\n\)*/\1/g;s/\n\(\n.*\)*/&&/[num];s///[samenum]
peut assez efficacement étayer cela. Quoi qu'il en soit, tant qu'il n'y a pas d'erreur flagrante dans la logique, je suis heureux - je pensais juste que j'avais dû manquer quelque chose.sed
- c'est un peu bizarre - ça devrait être sain selon la norme. xrat dit ... Les développeurs standard considéraient le comportement historique commun, qui supportait"\n*"
, mais pas"\n\{min,max\}", "\(...\)*"
, ou"\(...\)\{min,max\}"
, comme un résultat non intentionnel d'une implémentation spécifique, et ils supportaient à la fois la duplication et les expressions d'intervalle après les sous-expressions et les références arrières.( '*' )
ou d'une expression d'intervalle (voir point (5)), la référence arrière doit correspondre à la dernière (la plus à droite ) de ces chaînes. Je suis à peu près sûr d'avoir testé cela avec -minised
bien sûr, je testais quelque chose de bizarre avecminised
l'autre jour, de toute façon.Oui. La commande sed suivante supprime d'abord tous les espaces blancs de fin (
s/ *$//
), puis tout ce qui se termine jusqu'au dernier espace blanc (s/.* //
) inclus . Il vaut probablement la peine de remplacer les espaces littéraux par[[:blank:]]
pour capturer les tabulations et autres caractères de type espace.la source
la source