Nol mengisi angka menjadi 2 digit dengan sed

19

Memasukkan:

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

Output yang diinginkan:

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

Bagaimana saya bisa menambahkan 0jika hanya ada satu digit, misalnya 1di bagian "hari"? Saya memerlukan format tanggal ini: YYYYMM DD.

LanceBaynes
sumber

Jawaban:

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
sumber
Bisakah Anda menjelaskan cara kerjanya? Ini adalah pertama kalinya saya melihat \<[0-9]\>konstruk yang saya pikir adalah orang yang bertanggung jawab untuk mencocokkan satu digit tetapi tidak yakin apa yang disebut konstruk ini. Terima kasih.
sasuke
2
\ <berarti: mulai dari 'kata' ... [0-9] berarti satu digit dari 0 hingga 9 ... \> berarti: akhir dari 'kata' ... kata: token yang dibatasi spasi (atau dimulai / berakhir pada awal / akhir baris, untuk masing-masing \ <dan \>) ... PS. Saya baru saja mencoba tanda baca .. mereka juga pembatas.
Peter.O
1
Anda juga dapat melakukan ini tanpa menangkap tanda kurung: &dalam string pengganti akan menggunakan LHS yang cocok -sed 's/\<[0-9]\>/0&/'
glenn jackman
Oh, tidak sadar itu <>adalah batas kata dalam sintaks shell regex. Kalau dipikir-pikir, bahkan `sed 's / \ b [0-9] \ b / 0 & /' juga berfungsi. Terima kasih semuanya. :)
sasuke
@sasuke: <>adalah fitur regex yang diperluas (bukan dari shell, dengan demikian) ... tergantung pada versi dan opsi mana yang Anda gunakan, seddan shellkeduanya dapat menggunakan regex yang diperluas atau standar ... regex standar yang digunakan\<\>
Peter. O
18

Solusi lain: awk '{$2 = sprintf("%02d", $2); print}'

glenn jackman
sumber
2

Berikut ini adalah cara (non-sed) untuk menggunakan bash dengan regex yang diperluas .
Metode ini, memungkinkan ruang lingkup untuk melakukan pemrosesan garis individual yang lebih kompleks. (mis. lebih dari sekadar penggantian regex)

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

keluaran:

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
sumber
1

Saya akan melakukan sesuatu seperti ini:

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

Ini mengambil angka-angka kesepian, strip mereka dari spasi putih dengan grup ' ([0-9]) ', kemudian tempatkan kembali dengan 0 dan spasi putih ' 0\1 '.

The -Epilihan memungkinkan untuk ekspresi regex modern pada OSX (sehingga Anda tidak harus menggunakan "\"begitu sering), -rmelakukan hal yang sama pada sistem linux yang sudah saya uji.

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