我有一个包含以下内容的文件/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,"[ ,]")
在分隔符空格和逗号处分割输入并将它们写入 arraya
。for (i in a)
对于 awk 处理的每一行,它都会循环遍历数组a
split(a[i],b,"-")
中的每个元素a
在分隔符处再次拆分-
,然后将范围保存在 array 中b
。if(a[i]==NR||(b[2]!=""&&b[1]<=NR&&b[2]>=NR))
如果当前正在处理的行号awk
位于数组中a
,或者行号位于数组中的两个数字之间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
。