1行あたりのフィールド数が可変である次の形式のファイルがあります。
NC_000001.11_NM_001005484.2 69270 234 69037 65565 69037
NC_000001.11_NM_001005484.2 69511 475 69037 65565 69037
NC_000001.11_NM_001005484.2 69761 725 69037 65565 69037
NC_000001.11_NM_001385640.1 942155 20 942136 924432 925922 930155 931039 935772 939040 939272 941144 942136 942410 942559 943253 943698 943908
各行に対して最初の4つのフィールドを印刷したいと思います。残りのフィールド($ 5〜NF)の場合、このフィールドの値が$ 4の値より小さい場合は、そのフィールドを印刷したいと思います。
出力例:
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
いくつかのawkオプションを試しましたが、すべて失敗しました。 awkに初めて触れてくれて助けてくれてありがとう。
ベストアンサー1
出力でスペースを気にしない場合は、必要なものは次のとおりです。
$ 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
column
必要に応じて、パイプを介して視覚的な位置合わせを実行できます。
$ 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
そうでなければ、出力の間隔が入力の間隔のように見えるようにしたい場合(つまり、最初の4つのフィールドは1つ以上の空白として見え、残りは2つ以上の空白として表されます)、一部の行には4つ以下の空白しかありません。 。フィールドを選択してPOSIX awkを使用します(文字クラスと正規表現スペース用)。
$ 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 }
$ 4以降のフィールドをタブで区切る必要がある場合:
$ 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
またはスペースで区切る必要がある場合:
$ 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
上記は、入力のタブおよび/またはスペースの組み合わせに対して最初の4つのフィールド間のスペースを保持し、次に5番目以降のフィールドの前にタブを印刷します。これを使用して、同等のcolumn
アイテムが必要な場合は空白のままにできます。どちらも質問の入力と出力のように見えます。
out
上記のループで名前付きの新しい文字列を作成し、ループを変更するか、ループ内で変更するのではなく、ループの後に$0
一度割り当てます。これは、awkを変更するたびにそのフィールドに再構築する必要があり、awkを変更するたびに再分割する必要があるためです。フィールドに含まれるため、両方とも非効率的であり、フィールドの内容によって予期しないエラーが発生する可能性があるため、非常に特定の目的がない限り、ループ内で修正または修正しないでください。$0
$i
$i
$0
$0
$0
$0
$i