In addition to what Scrutinizer and RudiC have already suggested, you could also try:
echo 'Just using FS...'
awk -F'[^[:digit:]]*' '{$1=$1}1' file
printf '\nUsing FS and a for loop...\n'
awk -F'[^[:digit:]]*' '{for(i = 2; i <= NF; i++) printf("%s%s", $i, (i == NF) ? "\n" : " ")}' file
printf '\nUsing aplit() and a for loop...\n'
awk '
{ n=split($0, fields, /[^[:digit:]]*/)
for(i = 2; i <= n; i++)
printf("%s%s", fields, (i == n) ? "\n" : " ")
}' file
which, with your input file, produces the output:
Just using FS...
1 2 3 4
4 6 7 9
Using FS and a for loop...
1 2 3 4
4 6 7 9
Using aplit() and a for loop...
1 2 3 4
4 6 7 9
If you want to try this on a Solaris/SunOS system, change awk to /usr/xpg4/bin/awk , /usr/xpg6/bin/awk , or nawk .
The first example is simple but outputs an unwanted leading space. The 2nd and 3rd produce the desired output, one using the field separator to split fields and one using split() to split fields. The last two then use a for loop to print the desired fields (note that with the ERE used for FS and the split(), field 1 is always an empty string.)
I hadn't noticed that this thread had been closed when I posted my last suggestion. And, since I received a private message asking how my code worked, I'm going to reopen this thread. I agree that these two threads are related, but I feel that this thread is mostly about using field delimiters other than the default sequences of one or more blank (space and tab) characters, while the other thread is mostly about deleting selected fields from input lines.
From the private e-mail:
It is an extended regular expression (aka ERE) that matches any string of characters (specified by the asterisk at the end) that are not decimal digits (specified by the bracket expression [^[:digit:]] where [:digit:] inside square brackets refers to a single digit in the current locale and the circumflex as the first character in the bracket expression reverses the set of matched characters). Since this is an option-argument to the awk -F option, that ERE as the input field separator for lines being read by awk .
The 1st string printed is the data in the field. The 2nd string printed is the field separator or the line terminator.
That is a colon; not a semicolon. In awk (as in C and C++) the expression:
logical_expression ? true_result : false_result
evaluates to true_result if the logical_expression evaluates to true and evaluates to false_result otherwise. In this case:
(i == NF) ? "\n" : " "
returns a <newline> character to be printed as the line terminator if i is the number of the last field on the input line; otherwise it returns a <space> character to be printed as a field separator in the current output line.
Never apologize for asking questions. We want you to learn how this stuff works.
I hope this helps. Let us know if it is still not clear.