Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Input:

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

Desired output:

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

How can I add a 0 if there is only a single digit, e.g. 1 in the "day" part? I need this date format: YYYYMM DD.

share|improve this question
1  
+1 for a well formed question with desired output. –  SiegeX Mar 12 '11 at 11:10
add comment

3 Answers

up vote 7 down vote accepted
$ 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
share|improve this answer
    
Can you explain how this works? This is the first time I'm looking at the \<[0-9]\> construct which I think is the one responsible for matching the single digits but not sure what this construct is called. Thanks. –  sasuke Mar 12 '11 at 13:16
2  
\< means: start of a 'word' ... [0-9] means a single digit from 0 to 9 ... \> means: end of a 'word' ... word: a token which is whitespace delimited (or begins/ends at start/end of the line, for \< and \> respectively)... PS. I just tried punctuation marks.. they are also delimiters. –  Peter.O Mar 12 '11 at 13:46
1  
You can also do this without capturing parentheses: & in the replacement string will use the matched LHS -- sed 's/\<[0-9]\>/0&/' –  glenn jackman Mar 12 '11 at 14:33
    
Oh, wasn't aware that <> is a word boundary in shell regex syntax. Come to think of it, even `sed 's/\b[0-9]\b/0&/' also works. Thank you both. :) –  sasuke Mar 12 '11 at 15:18
    
@sasuke: <> is a feature of extended regex (not of the shell, as such)... depending on which version and which options you use, sed and the shell can both use either extended or standard regex ... standard regex uses \<\> –  Peter.O Mar 12 '11 at 17:19
show 2 more comments

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

share|improve this answer
    
+1 for an innovative solution. –  sasuke Mar 12 '11 at 15:09
    
+1: This is the most correct solution here even though it does use awk instead of sed –  D.Shawley Mar 12 '11 at 19:11
    
Actually, this doesn't work. You need to use awk '{$2=sprintf("%02d", $2)}; printf}' or better yet awk '{$2=sprintf("%02d", $2)}1' to save those poor little keystrokes –  SiegeX Mar 12 '11 at 19:18
    
to be more clear, your answer doesn't work as stated because the 'zero-pad' flag only works with the %d format specifier, not %s –  SiegeX Mar 12 '11 at 23:11
    
oops right. fixed –  glenn jackman Mar 13 '11 at 13:51
add comment

Here is a (non-sed) way to use bash with extended regex..
This method, allows scope to do more complex processing of individual lines. (ie. more than just regex substitutions)

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

output:

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
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.