views:

128

answers:

2

I want to write a Shell (AWK, Sed also fine) program to take as a input a SINGLE line of text.

Which will have arbitrarily spread integer strings in it. e.g

"12884 and 111933 are two numbers and 323232 is also a number"

I want the output to be

"12,884 and 1,11,933 are two numbers and 2,23,232 is also a number"

If this was PHP a simple preg_replace_callback would have served the purpose but I want this to be in shell. :/

Any pointers would of great help.

A: 
for line in $(echo "12884 and 111933 are two numbers and 323232 is also a number" 
    | tr ' ' '\n');
    do 
        if [ $line -eq $line 2> /dev/null ]; 
            then printf "%'d\n" $line;
        else 
            echo $line; 
        fi; 
    done | tr '\n' ' '

I understand this may be long and ugly but by now is the best I could do, I hope it will help.

Follows the explanation:

  • fist I split the line on more lines so I can loop and recognize which strings are number and which are not
  • then I test if the current string is a number
  • if it is a number I parse with the usage of printf
  • if it is not I simply echo it, leaving as it was
  • finish the loop and put everything back on one line
Alberto Zaccagni
"finish the loop and put everything back on one line"I do not think this ie being done properly in my case.I get '\n' printed in the line output
Akshar Prabhu Desai
My solution is indeed a bit messy, I used it on only one line and worked as expected, @Dennis Williamson's is much clearer. Use his
Alberto Zaccagni
+2  A: 

It's not necessary to split the line using tr. You can make use of Bash's word splitting feature:

line="12884 and 111933 are two numbers and 323232 is also a number"
for word in $line
do
    if [[ $word = *[^0-9]* ]]
    then
        printf "%s " $word
    else
        printf "%'d " $word
    fi
done

I've also used globbing to test for a sequence of digits rather than relying on something that creates an error or not depending on whether it's an integer.

Dennis Williamson
Did not know of the word splitting feature, thanks for pointing that out. +1.I think you have to correct that $foo var in the if test condition :P
Alberto Zaccagni
oops, fixed
Dennis Williamson