Reputation:
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!
Upvotes: 1
Views: 187
Reputation: 41454
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
Upvotes: 4
Reputation: 123568
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
Upvotes: 4
Reputation: 77105
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
Upvotes: 2