J'ai du mal à obtenir ma syntaxe sed pour ajouter un nombre variable de zéros de tête à un schéma d'organisation numérique. Les chaînes sur lesquelles j'opère apparaissent comme
1.1.1.1,Some Text Here
tirer parti de la syntaxe sed
sed -r ":r;s/\b[0-9]{1,$((1))}\b/0&/g;tr"
Je peux obtenir la réponse
01.01.01.01,Some Text Here
Cependant, ce que je recherche, c'est quelque chose à remplir jusqu'à 2 chiffres dans les champs 2 et 3 et 3 chiffres dans le champ 4 afin que tous les éléments soient d'une longueur standard à [0-9]. [0-9] { 2}. [0-9] {2}. [0-9] {3}
1.01.01.001,Some Text Here
Pour la vie de moi, je ne sais même pas comment modifier la frontière pour inclure les paramètres nécessaires pour accrocher aux seuls chiffres après une période. Je pense que cela a quelque chose à voir avec l'utilisation du \ b que je comprends correspond à zéro caractère à la limite d'un mot, mais je ne comprends pas pourquoi mes tentatives pour ajouter un point à la correspondance échouent comme suit:
sed -r ":r;s/\.\b[0-9]{1,$((1))}\b/0&/g;tr"
sed -r ":r;s/\b\.[0-9]{1,$((1))}\b/0&/g;tr"
Both cause the statement to hang
sed -r ":r;s/\b[0-9]\.{1,$((1))}\b/0&/g;tr"
sed -r ":r;s/\b[0-9]{1,$((1))}\.\b/0&/g;tr"
sed -r ":r;s/\b[0-9]{1,$((1))}\b\./0&/g;tr"
cause the statement to output:
1.01.01.1,Some Text Here
De plus, je m'attends à avoir des problèmes supplémentaires si la déclaration contient du texte comme:
1.1.1.1,Some Number 1 Here
Il est évident que j'ai besoin d'apprendre vraiment sed et toutes ses complexités. J'y travaille, mais je m'attends à ce que cette déclaration particulière continue de me causer des ennuis pendant un certain temps. Toute aide serait grandement appréciée.
EDIT: J'ai trouvé un moyen ... Cette déclaration semble faire ce que je cherche, mais il doit y avoir un moyen plus élégant de le faire.
sed -r ':r;s/\b[0-9]{1,1}\.\b/0&/;tr;:i;s/\b[0-9]{1,2},\b/0&/;ti;s/.//'
En outre, syntaxiquement, cela causera des problèmes si un format numérique similaire apparaît dans le texte ... similaire à:
1.1.1.1,Some Text Referring to Document XXX Heading 1.2.3
Dans ce cas, il en résultera:
1.01.01.001,Some Text Referring to Document XXX Heading 01.02.03
Résolu Merci à tous pour votre aide ici. J'ai d'abord résolu le problème avec la réponse que j'ai acceptée ci-dessous. Je sens que la solution a été déplacée dans Python dans le cadre d'une solution plus large tirant parti du tri ci-dessous:
def getPaddedKey(line):
keyparts = line[0].split(".")
keyparts = map(lambda x: x.rjust(5, '0'), keyparts)
return '.'.join(keyparts)
s=sorted(reader, key=getPaddedKey)
la source
sed -r ':r;s/\b[0-9]{1,1}\.\b/0&/;tr;:i;s/\b[0-9]{1,2},\b/0&/;ti;s/.//'
Cependant, j'aimerais savoir s'il existe une approche plus élégante.printf
(ou unprintf
appel dans Awk) peut être plus simple.Réponses:
Usage:
leading_zero.sh input.txt
Explication:
input.txt
output.txt
la source
perl
version ne supprime pas les barres obliques inverses.bash peut gérer cela. Ce sera beaucoup plus lent que Perl:
la source
printf
, l'outil sensé. (Awk aprintf
également et est mieux conçu quebash
pour le traitement de texte.) Voir aussi Pourquoi l'utilisation d'une boucle shell pour traiter du texte est-elle considérée comme une mauvaise pratique?Vous n'avez pas spécifiquement demandé de
perl
solution mais en voici une quand même. Personnellement, je pense que c'est un peu plus facile à lire, surtout lorsqu'il est divisé en plusieurs lignes.Voici d'abord le one-liner:
Ses résultats:
Et voici le
perl
script éclaté et commenté (le-n
drapeau met unewhile read; do ... done
boucle implicite autour du code):la source
awk
fonctionnerait aussi - même principe en utilisantprintf
Voici une approche possible:
sed -E 's/([0-9]*\.)/0\1/g;s/.//;s/([0-9]*,)/00\1/'
Exemples
Travaillez également avec cette chaîne:
... et cette chaîne:
la source
Explication:
La méthode utilisée est ici de regarder les voisinages du numérique et de prendre des mesures en fonction de cela. Ainsi, les 2e et 3e chiffres voient un point des deux côtés tandis que le 4e chiffre voit le point à gauche et une virgule à droite.
Le $ 1 est défini lorsque l'expression régulière prend le chemin des 2ème ou 3ème nombres et en conséquence le remplissage de précision est 2. OTOH, pour le 4ème nombre, le remplissage est de 3.
% cat file.txt
Résultats:
la source