1

I have this line

word1 word2 1234 4567 word3 8901 word4 word5 2541 5142 word5

I want to split this line in order to insert a line break before a numeric field or before an alphanumeric field that is just after a numeric field, so the output would be:

word1 word2
1234
4567
word3
8901
word4 word5
2541 
5142 
word5

All alphanumeric fields begin with letters

1

Sounds like you want to preserve spaces between alphanumeric words and converts all other ones to newlines, so maybe:

perl -pe 's{([^\d\s]\S*\s+)(?=\S*[^\d\s])|\s+}{$1//"\n"}ge'
1
echo "word1 word2 1234 4567 word3 8901 word4 word5 2541 5142 word5" |perl -pe 's/(\s)([0-9]+)/$1\n$2/g; s/(\s)([0-9]+)(\s+)([a-zA-Z])/$1$2\n$4/g;'

Explanation:

  • perl -pe: run the following Perl script on each line of input and print results
  • s/(\s)([0-9]+)/$1\n$2/g: whitespace + numeric field -> whitespace + newline + numeric field
  • s/(\s)([0-9]+)(\s+)([a-zA-Z])/$1$2\n$4/g: whitespace + numeric field + whitespace + alphanumeric field -> whitespace + numeric field + newline + alphanumeric field
  • the g at the end of each replacement means 'global'--do it for the entire line
1

Put the following code in an awk script. Let's say the script is called do_magic.awk

#!/usr/bin/awk -f

{
  str=$1
   for (i=2;i<=NF;++i) 
      if ($i ~ /^[0-9]+/) str = str "\n" $i "\n"
      else str = str " " $i
       gsub(/\n[[:space:]]*/,"\n",str)
       print str
}

Call the script using

do_magic.awk yourfile

Result is:

word1 word2
1234
4567
word3
8901
word4 word5
2541
5142
word5

PS: I had somehow a working solution I thought. On freenode #awk, geirha provided the full answer. So credits go to him!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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