Numéros de remplissage zéro à 2 chiffres avec sed


19

Contribution:

201103 1 /mnt/hdd/PUB/SOMETHING
201102 7 /mnt/hdd/PUB/SOMETH ING
201103 11 /mnt/hdd/PUB/SO METHING
201104 3 /mnt/hdd/PUB/SOMET HING
201106 1 /mnt/hdd/PUB/SOMETHI NG

Sortie désirée:

201103 01 /mnt/hdd/PUB/SOMETHING
201102 07 /mnt/hdd/PUB/SOMETH ING
201103 11 /mnt/hdd/PUB/SO METHING
201104 03 /mnt/hdd/PUB/SOMET HING
201106 01 /mnt/hdd/PUB/SOMETHI NG

Comment puis-je ajouter un 0s'il n'y a qu'un seul chiffre, par exemple 1dans la partie "jour"? J'ai besoin de ce format de date: YYYYMM DD.

Réponses:


13
$ sed 's/\<[0-9]\>/0&/' ./infile
201103 01 /mnt/hdd/PUB/SOMETHING
201102 07 /mnt/hdd/PUB/SOMETH ING
201103 11 /mnt/hdd/PUB/SO METHING
201104 03 /mnt/hdd/PUB/SOMET HING
201106 01 /mnt/hdd/PUB/SOMETHI NG

Pouvez-vous expliquer comment cela fonctionne? C'est la première fois que je regarde la \<[0-9]\>construction qui, je pense, est celle responsable de la correspondance des chiffres, mais je ne sais pas comment cette construction est appelée. Merci.
sasuke

2
\ <signifie: début d'un 'mot' ... [0-9] signifie un seul chiffre de 0 à 9 ... \> signifie: fin d'un 'mot' ... mot: un jeton délimité par des espaces (ou commence / fin au début / fin de la ligne, respectivement pour \ <et \>) ... PS. J'ai juste essayé les signes de ponctuation .. ce sont aussi des délimiteurs.
Peter.O

1
Vous pouvez également le faire sans capturer les parenthèses: &dans la chaîne de remplacement, utilisez le LHS correspondant -sed 's/\<[0-9]\>/0&/'
glenn jackman

Oh, je ne savais pas que c'était <>une limite de mot dans la syntaxe des expressions rationnelles du shell. À bien y penser, même `sed 's / \ b [0-9] \ b / 0 & /' fonctionne également. Merci à vous deux. :)
sasuke

@sasuke: <>est une caractéristique de regex étendu (non de la coquille, en tant que telle) ... selon la version et les options que vous utilisez, sedet shellpeuvent aussi bien utiliser soit prolongée ou standards regex ... utilisations standard regex\<\>
Peter. O


2

Voici une façon (non sed) d'utiliser bash avec regex étendu .
Cette méthode permet à scope de faire un traitement plus complexe de lignes individuelles. (c.-à-d. plus que de simples substitutions d'expression régulière)

while IFS= read -r line ; do
    if [[ "$line" =~ ^(.+\ )([0-9]\ .+)$ ]]  
    then echo "${BASH_REMATCH[1]}0${BASH_REMATCH[2]}" 
    else echo "$line"
    fi
done <<EOF
201103 1 /mnt/hdd/PUB/SOMETHING
201102 7 /mnt/hdd/PUB/SOMETH ING
201103 11 /mnt/hdd/PUB/SO METHING
201104 3 /mnt/hdd/PUB/SOMET HING
201106 1 /mnt/hdd/PUB/SOMETHI NG
EOF

production:

201103 01 /mnt/hdd/PUB/SOMETHING
201102 07 /mnt/hdd/PUB/SOMETH ING
201103 11 /mnt/hdd/PUB/SO METHING
201104 03 /mnt/hdd/PUB/SOMET HING
201106 01 /mnt/hdd/PUB/SOMETHI NG

1

Je ferais quelque chose comme ça:

sed -E 's/ ([0-9]) / 0\1 /' ./input

Cela saisit les nombres solitaires, les supprime des espaces blancs avec un groupe ' ([0-9]) ', puis les remet en place avec 0 et un espace blanc ' 0\1 '.

L' -Eoption permet des expressions RegEx modernes sur OSX (vous n'avez donc pas à utiliser "\"si souvent), -rfait la même chose sur les systèmes Linux que j'ai testés.


-1
while read a b c
do 
new_format=$(printf "%02d" $b)
echo "$a $new_format $c"
done </tmp/input
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.