If you don't care about the white space in your output then all you need is:
$ cat tst.awk
{
out = $1 OFS $2 OFS $3 OFS $4
for (i=5; i<=NF; i++) {
if ( $i < $4 ) {
out = out OFS $i
}
}
print out
}
$ awk -f tst.awk file
NC_000001.11_NM_001005484.2 69270 234 69037 65565
NC_000001.11_NM_001005484.2 69511 475 69037 65565
NC_000001.11_NM_001005484.2 69761 725 69037 65565
NC_000001.11_NM_001385640.1 942155 20 942136 924432 925922 930155 931039 935772 939040 939272 941144
which you can pipe to column
to visually align if you like:
$ awk -f tst.awk file | column -t
NC_000001.11_NM_001005484.2 69270 234 69037 65565
NC_000001.11_NM_001005484.2 69511 475 69037 65565
NC_000001.11_NM_001005484.2 69761 725 69037 65565
NC_000001.11_NM_001385640.1 942155 20 942136 924432 925922 930155 931039 935772 939040 939272 941144
Otherwise if you want the spacing in the output to look like the spacing in the input (i.e. what looks like 1 or more blanks for the first 4 fields and 2 or more for the rest of the fields) and assuming some lines might only have 4 or less fields then using any POSIX awk (for character classes and regexp intervals):
$ cat tst.awk
BEGIN { OFS="\t" }
match($0,/([^[:space:]]+[[:space:]]+){3}[^[:space:]]+/) {
out = substr($0,RSTART,RLENGTH)
for (i=5; i<=NF; i++) {
if ( $i < $4 ) {
out = out OFS $i
}
}
$0 = out
}
{ print }
If the fields after $4 should be tab-separated:
$ awk -f tst.awk file
NC_000001.11_NM_001005484.2 69270 234 69037 65565
NC_000001.11_NM_001005484.2 69511 475 69037 65565
NC_000001.11_NM_001005484.2 69761 725 69037 65565
NC_000001.11_NM_001385640.1 942155 20 942136 924432 925922 930155 931039 935772 939040 939272 941144
or if they should be separated by blanks:
$ awk -f tst.awk file | column -s$'\t' -t
NC_000001.11_NM_001005484.2 69270 234 69037 65565
NC_000001.11_NM_001005484.2 69511 475 69037 65565
NC_000001.11_NM_001005484.2 69761 725 69037 65565
NC_000001.11_NM_001385640.1 942155 20 942136 924432 925922 930155 931039 935772 939040 939272 941144
The above retains the white space between the first 4 fields so that'll just be whatever combination of tabs and/or blanks you have in your input, and then prints a tab before every 5th and subsequent field which you can use column
to change to equivalent blanks if you like, both of which look like the input and output in your question.
I'm building a new string named out
in the loops above and assigning it to $0
once after the loops rather than modifying $0
or $i
within the loops because each time you change $i
awk has to re-build $0
from it's fields, and each time you change $0
awk has to resplit $0
into fields so both are inefficient and can lead to unexpected errors depending on the contents of the fields and therefore you should not modify $0
or $i
within a loop unless you have a very specific purpose in mind that requires you to do so.