Zahlen mit sed auf 2 Ziffern auffüllen

19

Eingang:

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

Gewünschte Ausgabe:

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

Wie kann ich eine hinzufügen, 0wenn es nur eine Ziffer gibt, z. B. 1im "Tag" -Teil? Ich benötige dieses Datumsformat: JJJJMM TT.

LanceBaynes
quelle

Antworten:

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
SiegeX
quelle
Können Sie erklären, wie das funktioniert? Dies ist das erste Mal, dass ich mir das \<[0-9]\>Konstrukt anschaue, das meiner Meinung nach für die Zuordnung der einzelnen Ziffern verantwortlich ist, aber nicht sicher ist, wie dieses Konstrukt heißt. Vielen Dank.
Sasuke
2
\ <bedeutet: Beginn eines 'Wortes' ... [0-9] bedeutet eine einzelne Ziffer von 0 bis 9 ... \> bedeutet: Ende eines 'Wortes' ... Wort: ein Token, das durch Leerzeichen getrennt ist (oder beginnt / endet am Anfang / Ende der Zeile für \ <bzw. \>) ... PS. Ich habe gerade Satzzeichen ausprobiert. Sie sind auch Trennzeichen.
Peter.O
1
Sie können dies auch tun, ohne Klammern zu setzen: &In der Ersatzzeichenfolge wird der passende LHS -sed 's/\<[0-9]\>/0&/'
Glenn Jackman
Oh, war mir nicht bewusst, dass dies <>eine Wortgrenze in der Shell-Regex-Syntax ist. Kommen Sie und denken Sie darüber nach, auch das / \ b [0-9] \ b / 0 & / von sed funktioniert. Danke euch beiden. :)
sasuke
@sasuke: <>ist ein Merkmal der erweiterten Reguläre Ausdrücke (nicht von der Schale, die als solche) ... je nachdem , welche Version und welche Optionen Sie verwenden, sedund die shellkönnen beide entweder erweitert oder Standard regex ... Standard regex Anwendungen\<\>
Peter. O
18

Eine andere Lösung: awk '{$2 = sprintf("%02d", $2); print}'

Glenn Jackman
quelle
2

Hier ist eine (nicht gesetzte) Möglichkeit, bash mit erweitertem regulären Ausdruck zu verwenden .
Diese Methode ermöglicht die komplexere Verarbeitung einzelner Zeilen. (dh mehr als nur Regex-Substitutionen)

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

Ausgabe:

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
Peter.O
quelle
1

Ich würde so etwas machen:

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

Dies greift nach einsamen Zahlen, entfernt sie mit einer Gruppe von Leerzeichen ' ([0-9]) 'und setzt sie mit 0 und Leerzeichen wieder ein ' 0\1 '.

Die -EOption ermöglicht moderne RegEx-Ausdrücke unter OSX (Sie müssen sie also nicht "\"so oft verwenden). -rDas Gleiche gilt für die von mir getesteten Linux-Systeme.

Eric
quelle
-1
while read a b c
do 
new_format=$(printf "%02d" $b)
echo "$a $new_format $c"
done </tmp/input
Mohamed ELKHALIFI
quelle