Azzera i numeri a 2 cifre con sed


19

Ingresso:

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

Uscita desiderata:

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

Come posso aggiungere un 0se c'è una sola cifra, ad es. 1Nella parte "giorno"? Ho bisogno di questo formato data: AAAAMM GG.

Risposte:


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

Puoi spiegare come funziona? Questa è la prima volta che guardo il \<[0-9]\>costrutto che ritengo sia il responsabile della corrispondenza delle singole cifre ma non sono sicuro di come si chiama questo costrutto. Grazie.
sasuke,

2
\ <significa: inizio di una 'parola' ... [0-9] significa una singola cifra da 0 a 9 ... \> significa: fine di una 'parola' ... parola: un token che è delimitato da spazi bianchi (o inizia / termina all'inizio / fine della riga, rispettivamente per \ <e \>) ... PS. Ho appena provato i segni di punteggiatura .. sono anche delimitatori.
Peter

1
Puoi anche farlo senza catturare le parentesi: & nella stringa di sostituzione verrà utilizzato l'LHS abbinato -sed 's/\<[0-9]\>/0&/'
glenn jackman

Oh, non sapevo che <>fosse un limite di parole nella sintassi della regex della shell. Vieni a pensarci, anche "sed 's / \ b [0-9] \ b / 0 & /' funziona anche. Grazie ad entrambi. :)
sasuke,

@sasuke: <>è una funzionalità di regex esteso (non della shell, in quanto tale) ... a seconda della versione e delle opzioni che usi, sede shellpuoi usare sia esteso che standard regex ... usa regex standard\<\>
Peter. O


2

Ecco un modo (non sed) di usare bash con regex esteso .
Questo metodo consente all'ambito di eseguire elaborazioni più complesse di singole linee. (es. più di semplici sostituzioni 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

produzione:

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

Vorrei fare qualcosa del genere:

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

Questo afferra numeri solitari, li spoglia di spazi bianchi con un gruppo ' ([0-9]) ' , quindi li posiziona di nuovo con 0 e riempimento di spazi bianchi ' 0\1 '.

L' -Eopzione consente le moderne espressioni RegEx su OSX (quindi non è necessario utilizzarle "\"così spesso), -rfa la stessa cosa sui sistemi Linux che ho testato.


-1
while read a b c
do 
new_format=$(printf "%02d" $b)
echo "$a $new_format $c"
done </tmp/input
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.