Sed ile 2 basamağa sıfır doldurma


19

Giriş:

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

Istenilen çıktı:

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

0Yalnızca tek bir basamak varsa nasıl ekleyebilirim , örneğin 1"gün" bölümünde? Şu tarih biçimine ihtiyacım var: YYYYAAGG.

Yanıtlar:


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

Bunun nasıl çalıştığını açıklayabilir misiniz? Bu, ilk kez \<[0-9]\>tek basamakları eşleştirmekten sorumlu olduğunu düşündüğüm yapıya bakıyorum, ancak bu yapının ne denildiğinden emin değilim. Teşekkürler.
sasuke

2
\ <şu anlama gelir: 'kelimenin' başlangıcı ... [0-9] 0 ile 9 arasında tek bir rakam anlamına gelir ... \> şu anlama gelir: 'kelimenin' sonu ... kelimesinin: boşlukla sınırlandırılmış bir belirteç (veya sırasıyla \ <ve \> için satırın başında / sonunda başlar / biter) ... PS. Noktalama işaretlerini yeni denedim .. onlar da sınırlayıcılar.
Peter.O

1
Bunu parantez yakalamadan da yapabilirsiniz: &yedek dizede eşleşen LHS kullanılır -sed 's/\<[0-9]\>/0&/'
glenn jackman

Oh, bunun <>kabuk normal ifade sözdiziminde bir kelime sınırı olduğunun farkında değildi . Düşünmeye gel, hatta `sed 's / \ b [0-9] \ b / 0 & /' bile çalışır. İkinize de teşekkürler. :)
sasuke

@sasuke: <>bir özelliğidir genişletilmiş regex (değil gibi kabuk, ...) hangi sürümü ve kullanmak seçenekleri bağlı olarak sedve shellhem kullanım ya edebilir uzatılmış veya standart düzenli ifade ... Standart regex kullanımları\<\>
Peter. Ey


2

Genişletilmiş regex ile bash kullanmanın (sed olmayan) bir yoludur .. Bu yöntem, kapsamın ayrı satırların daha karmaşık işlenmesini sağlar. (yani, normal regex ikamelerinden daha fazlası)

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

çıktı:

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

Böyle bir şey yapardım:

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

Bu, yalnız sayıları yakalar, bir grupla boşlukları ayırır ' ([0-9]) ', sonra 0 ve boşluk dolgusu ile tekrar yerleştirir ' 0\1 '.

Bu -Eseçenek, OSX'te modern RegEx ifadelerine izin verir (bu "\"nedenle çok sık kullanmanız gerekmez ), -rtest ettiğim linux sistemlerinde de aynı şeyi yapar.


-1
while read a b c
do 
new_format=$(printf "%02d" $b)
echo "$a $new_format $c"
done </tmp/input
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.