次の内容のファイルがあります/tmp/a.txt
。
1
2
3
4
5
を使用して、AWK
ユーザーに次の任意の形式で範囲を指定し、一致する行を印刷するように求めます。
カンマ区切り
1,2,3
空間分離
1 2 3
範囲内で使用 -
1-3
予想出力:
1
2
3
以下は、ユーザー入力をキャプチャするためのサンプルawkコマンドです。必要な出力を得るには、ここに何を入力する必要がありますか?
awk 'BEGIN { printf "Enter the range: " ; getline name < "-" }{?}' /tmp/a.txt
答え1
次のコマンドを使用できますawk
。
awk 'BEGIN { printf "Enter the range: " ; getline r < "-"; split(r,a,"[ ,]")} \
{for (i in a){split(a[i],b,"-"); if(a[i]==NR||(b[2]!=""&&b[1]<=NR&&b[2]>=NR)){print}}}' file
説明する:
printf "Enter the range: " ; getline r < "-";
質問からコピーされた(ユーザー入力を変数として読み取るr
)split(r,a,"[ ,]")
区切り文字スペースとカンマで入力を分割して配列に書き込みますa
。for (i in a)
awkが処理する各行に対して配列を繰り返します。a
split(a[i],b,"-")
の各要素はa
区切り文字で再分割され、-
範囲は配列に格納されますb
。if(a[i]==NR||(b[2]!=""&&b[1]<=NR&&b[2]>=NR))
現在処理中の行番号がawk
配列にあるa
場合、または行番号が配列の2つの数字の間にある場合b
...{print}
...行を印刷します。
組み合わせた入力を使用することもできます。
1-3,4 5 7-13
答え2
NR
行番号()を入力範囲と一致させたいのか、行全体($0
)または最初のフィールドの$1
値()と一致させたいのかはわかりません。試してみてください。
awk '
BEGIN {printf "Enter the range: "
getline ANS < "/dev/tty"
for (n=split (ANS, T, "[ ,]"); n; n--) {for (m=split (T[n], R, "-"); m; m--) TGT[R[m]]
for (i=R[1]+1; i<R[2]; i++) TGT[i]
}
}
$1 in TGT
' file
Enter the range: 1-3
1
2
3
または$1
に変更します。$0
NR