
次の内容のファイルがあります/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