Question

I have an awk question, let's say I have this:

up2left3right

I want to use awk to change it to this:

up
up
left
left
left
right

Any ideas on how this is possible? Thanks in advance!

Was it helpful?

Solution

Here is a gnu awk version (due to RS and RT)

echo "up2left3right" | awk  '{for (i=1;i<=(RT?RT:1);i++)  if (NF) print $0}' RS="[0-9]"
up
up
left
left
left
right

It changes the Record Separator to a number.
Then the RT stores the RS used and we uses a loop to repeat the data.


Updated version that now works with number larger than 9 (multiple digits)
Also added \n in RS to work correctly at end of line and if multiple line

awk '{i=RT=="\n"?1:RT;while(i--) if (NF) print $0}' RS="[0-9]+|\n" file

echo -e "up3left12right\ntest4more" | awk '{i=RT=="\n"?1:RT;while(i--) if (NF) print $0}' RS="[0-9]+|\n"
up
up
up
left
left
left
left
left
left
left
left
left
left
left
left
right
test
test
test
test
more

OTHER TIPS

Another option would be to use perl:

$ echo up2left3right | perl -pe 's/([A-Za-z]+)(\d+)/"$1\n" x $2/gse;'
up
up
left
left
left
right

Now with counts greater than 10:

$ echo up2down10left2right | perl -pe 's/([A-Za-z]+)(\d+)/"$1\n" x $2/gse;'
up
up
down
down
down
down
down
down
down
down
down
down
left
left
right

Here is possible way with regular awk:

$ echo "up2left3right1wrong2boo" | 
awk '{x=gsub(/[0-9]+/," & ");for(i=1;i<=x*2;i+=2){while($(i+1)--)print $i};if(i)print $i}'
up
up
left
left
left
right
wrong
wrong
boo

We basically create a space before and after a number and loop through each element. Once we encounter a word number pair, we use while loop to continue printing the word until number is exhausted. If word exists stand alone then testing with if loop we print it.

Though it will break where word is missing number and is followed by words with numbers. For following case it will consider rightwrong as one word:

up2left3rightwrong2
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top