Нульове заповнення чисел до 2 цифр з sed


19

Вхід:

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

Бажаний вихід:

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

Як я можу додати, 0якщо є лише одна цифра, наприклад, 1у частині "день"? Мені потрібен цей формат дати: YYYYMM DD.

Відповіді:


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

Чи можете ви пояснити, як це працює? Це перший раз, коли я дивлюся на \<[0-9]\>конструкцію, яка, на мою думку, відповідає за відповідність однозначних цифр, але не впевнена, як називається ця конструкція. Спасибі.
Саске

2
\ <означає: початок 'слова' ... [0-9] означає одну цифру від 0 до 9 ... \> означає: кінець 'слова' ... слово: маркер, який обмежений пробілом (або починається / закінчується на початку / кінці рядка, для \ <і \> відповідно) ... PS. Я просто спробував розділові знаки .. вони теж роздільники.
Пітер.О

1
Ви також можете це зробити, не захоплюючи дужки: &у рядку заміни буде використано відповідне LHS -sed 's/\<[0-9]\>/0&/'
glenn jackman

О, не знав, що <>це слово межа в синтаксисі регексу оболонки. Подумайте над тим, що навіть `sed 's / \ b [0-9] \ b / 0 & /' також працює. Дякую обом. :)
sasuke

@sasuke: <>це особливість розширеного регулярного вираження (не оболонки як такої) ... залежно від того, яку версію та які параметри ви використовуєте, sedа також shellможна використовувати або розширений, або стандартний регулярний вираз ... стандартний регекс використовує\<\>
Пітер. O


2

Ось (не-sed) спосіб використання bash з розширеним регулярним виразом .
Цей метод дозволяє використовувати більш складну обробку окремих рядків. (тобто більше, ніж просто заміни регулярного вираження)

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

вихід:

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

Я б зробив щось подібне:

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

Це захоплює одинокі номери, позбавляє їх білого простору з групою ' ([0-9]) ', потім повертає їх назад з 0 і пробілами ' 0\1 '.

Ця -Eопція дозволяє використовувати сучасні вирази RegEx на OSX (тому вам не доведеться користуватися "\"так часто), -rте ж саме робиться і в системах Linux, які я тестував.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.