Garniture 3 derniers caractères d'une ligne SANS l'aide de sed, ou perl, etc
J'ai un script shell de la sortie de données comme ceci:
1234567890 *
1234567891 *
J'ai besoin de retirer SEULEMENT les trois derniers caractères " *". Je sais que je peux le faire via
(whatever) | sed 's/\(.*\)...//'
Mais je NE veux PAS utiliser sed pour des raisons de vitesse. Il sera toujours le même 3 derniers caractères.
Tout moyen rapide de nettoyage de la sortie?
- vous êtes à partir de votre question avec une hypothèse incorrecte (qui
sed
vont vous ralentir). - pax - je crois que les expressions régulières prendre plus de temps que de simples opérations sur des chaînes de caractères. Je ne pense pas que je me trompe, mais n'hésitez pas à montrer le contraire...
- Ah, un défi. J'aime les défis 🙂 Voir ma mise à jour. Réponse courte. Complexe REs (avec lookaheads et les trackbacks et tout ce genre de trucs) est plus lent que le code dédié. Mais la vôtre n'est pas un complexe de RÉ. La compilation de l'analyseur sera assez rapide, même par rapport à des code. Certes, la différence de temps ne sera pas pertinente pour quelque chose qui se passe une fois par heure (si il prend 0,4 secondes ou 0,8 secondes ne doit pas être un sujet de préoccupation).
- Pouvez-vous dire autre chose sur les données? (sera-t-il toujours être 13 caractères par ligne?) Aussi quelle plateforme vous utiliser?
- c'est un peu dur à accepter votre affirmation que sed va en quelque sorte de ne pas être assez rapide ... vous avez déjà déclaré que la sortie est à venir à partir d'un script shell. Il est pratiquement impossible pour les sed pour être le goulot d'étranglement dans un tel pipeline! En d'autres termes, si la vitesse est d'une telle préoccupation, alors vous pourriez obtenir plus d'avantages de se concentrer sur le reste de votre code.
- En acceptant de 100% avec Zac, d'ailleurs, le seul moyen d'une expression régulière peut vous ralentir ici est de savoir si vous êtes en utilisant une POSIX NFA moteur ou la NFA moteur et vous n'avez pas de match. awk qui utilise un DFA avec une bonne regex sera pas vous ralentir.
Vous devez vous connecter pour publier un commentaire.
En supposant que toutes les données sont formatées comme votre exemple, utilisez " couper ' pour obtenir la première colonne.
ou pour obtenir les 10 premiers caractères.
cut -c 1-10 $file
.Voici une ancienne unix astuce pour enlever les 3 derniers caractères à partir d'une ligne qui
ne fait aucune utilisation de sed OU awk...
À la différence de l'exemple précédent à l'aide de "couper", cela ne nécessite pas la connaissance de la longueur de la ligne.
sed
,perl
ou etc. j'ai pris ça pour dire aucun outil externe.Je peux vous garantir que
bash
tout seul ne sera pas plus vite que lesed
pour cette tâche. Le démarrage d'un processus externe, dansbash
est généralement une mauvaise idée, mais seulement si vous faites beaucoup.Donc, si vous êtes à partir d'une
sed
processus de chaque ligne de vos commentaires, je serais intéressé. Mais vous n'êtes pas. Vous avez seulement besoin de commencer unsed
qui fera tout le travail pour vous.Cependant, vous pouvez trouver que les
sed
sera un peu plus vite que votre version:Tout cela n'est supprimer les trois derniers caractères de chaque ligne, plutôt que de se substituer à l'ensemble de la ligne avec une version plus courte de lui-même. Maintenant, peut-être plus moderne RE les moteurs de l'optimisation de votre commande, mais pourquoi prendre le risque.
Pour être honnête, la seule façon que je peux penser que ce serait plus rapide serait de la main de l'artisanat de votre propre C-filtre basé sur le programme. Et la seule raison que peut être plus rapide que
sed
est parce que vous pouvez profiter du supplément de connaissances que vous avez sur vos besoins de traitement (sed
doit permettre généralisé procession donc peut être plus lent à cause de cela).Ne pas oublier l'optimisation mantra: "la Mesure, ne pas le deviner!"
Si vous vraiment souhaitez faire une ligne à la fois dans
bash
(et je maintiens que c'est une mauvaise idée), vous pouvez utiliser:Vous pouvez également déterminer si vous avez réellement besoin une amélioration de la vitesse. Si vous traitez les lignes comme un gros morceau, vous verrez que
sed
est beaucoup rapide. Tapez les commandes suivantes:et de l'exécuter. Voici les résultats sur mon (pas très rapide) R40 ordinateur portable:
C'est 20 000 lignes en moins d'une seconde, assez bon pour quelque chose qui n'est faite chaque heure.
sed
). Quesed
commande facile grâce à 20K lignes en moins d'une seconde sur ma merde vieux IBM ThinkPad R40.for i in {1..20000}; do echo "line of text...XXX"; done | time -p sed 's/...$//' >/dev/null
- l'élimination decat
ethead
et au moins un fichier. Même si vous avez ajouté en arrière de la sortie de diagnostic, "for i in 4 16 64 256 1024 4096 16384 65536"for i in x x x x x x x x
sed
commande!Les deux
awk
etsed
sont beaucoup plus rapide, mais si vous pensez que c'questions n'hésitez pas à utiliser l'une des opérations suivantes:Si les caractères que vous souhaitez supprimer sont toujours à la fin de la chaîne
Si elles peuvent apparaître n'importe où dans la chaîne et que vous souhaitez seulement de supprimer ceux qui sont à la fin
Les pages man de toutes les commandes expliquer ce qu'il se passe.
Je pense que vous devriez utiliser
sed
, si.Remarque: Cette réponse est un peu censé être une blague, mais en fait elle fonctionne...
Vous pouvez remplacer
cat somedata.txt
avec une autre commande.gcc
avectcc
(tinyc) et je suis sûr que le 'compilation' surcharge être trivial. Surtout si vous n'avez jamais écrire un fichier binaire, mais onttcc
l'exécuter immédiatement.Range: bytes=0-...
en-tête. 😉Vous pouvez essayer de
head
lui-même devrait être plus rapide quesed
oucut
car il n'y a pas de regex ou le délimiteur de correspondance, mais en invoquant un pour chaque ligne séparément serait probablement plus importants que.Si le script toujours sorties lignes de 10 caractères, suivie par un supplément de 3 (en d'autres termes, vous voulez juste les 10 premiers caractères), vous pouvez utiliser
Si elle génère un nombre incertain de non-caractères d'espace, suivi d'un espace puis 2 autres caractères supplémentaires (en d'autres termes, vous voulez juste le premier champ), vous pouvez utiliser
... comme dans majhool commentaire plus tôt. En fonction de votre plate-forme, vous pouvez également avoir colrm, qui, encore une fois, si les lignes sont d'une longueur fixe:
Une autre réponse s'appuie sur les troisième à dernier caractère étant un espace. Cela fonctionne avec (presque) n'importe quel caractère dans cette position et qu'il ne "SANS l'aide de sed, ou perl, etc....":
Si vos lignes sont de longueur fixe de changer le
echo
à:ou
mais chacune de ces est certainement beaucoup plus lent que
sed
.Pas besoin de couper ou de magie, en bash, vous pouvez couper une chaîne de caractères comme suit:
Voir http://tldp.org/LDP/abs/html/string-manipulation.html
Vous pouvez utiliser awk juste pour imprimer le "terrain" d'abord si il n'y aura pas d'espaces (ou si il y aura de, modifier le séparateur'.
J'ai mis les champs que vous avez eu le dessus dans un fichier et cela a fait
Je ne sais pas si c'est mieux.
qu'entendez-vous ne voulez pas utiliser sed/awk pour des raisons de vitesse? sed/awk sont plus rapides que le shell de tout lire en boucle pour le traitement des dossiers.
avec shell bash