我试图在第 5 到 5 + Y 行获取 X 列中的值。我猜有一种快速的方法可以使用awk
. 这是怎么做到的?
3 回答
我认为这对你有用,未经测试:
awk 'NR >= 5 && NR <= 5 + Y { print $X }' file.txt
显然,用X
和Y
代替一些真实的价值。
编辑:
如果X
和Y
是 shell 变量:
awk -v column="$X" -v range="$Y" 'NR >= 5 && NR <= 5 + range { print $column }' file.txt
如果通过“列”表示您有一个文件,其中包含逗号分隔的字段,并且您想要提取特定字段,那么接受的答案就可以很好地做到这一点。回顾一下,
awk -F , 'NR==5 { print $6 }' file
从逗号分隔文件的第 5 行中提取第六个字段。如果您的分隔符不是逗号,请将其他内容作为参数传递给-F
选项。(使用 GNU Awk,您可以将正则表达式传递-F
给指定相当复杂的列分隔符,但如果您需要,请查找有关该特定场景的更具体的问题。)
如果“列”是指一行中的固定字符位置,则该substr
函数会执行此操作。
awk 'NR == 5 { print substr($0, 6) }' file
打印第六列及其之后的所有内容。如果要限制为固定宽度,
awk 'NR == 5 { print substr($0, 6, 7) }' file
在第 5 行打印从偏移量 6 开始的七个字符(Awk 索引从 1 开始,因此偏移量 1 是行上的第一个字符)。如果您不知道要提取多少个字符,但想要一个数字,Awk 很方便允许您从字符串的开头提取数字:
awk 'NR == 5 { print 0 + substr($0, 6, 7) }' file
将提取相同的 7 个字符,然后将结果强制转换为数字,有效地修剪任何非数字后缀,然后打印出来。
在最一般的情况下,您可能希望对提取的值执行进一步拆分。
awk 'NR == 5 { split(substr($0, 6), a, /:/); print a[1] }' file
将在正则表达式上提取的子字符串/:/
(在这种简单的情况下,正则表达式仅匹配文字冒号字符)到数组a
中。然后我们打印 的第一个元素a
,这意味着我们放弃从子字符串中的第一个冒号开始的所有内容,该冒号从索引 6 开始,一直延伸到第 5 行的行尾。
(为了让您不必查找它,$0
是整个当前输入行。Awk 逐行处理一个文件,依次在每一行上运行脚本的主体。如果您需要将 shell 变量公开给 Awk,awk -v awkvariable="$shellvariable"
这样做.)
使用 awk 打印第 5 到 10 行的第 2 列:
awk 'NR==5,NR==10 {print $2}' <file # white space delim. columns
awk 'NR==5,NR==10 {print $2}; NR==10 {exit}' <file # optimized
awk -F: 'NR==5,NR==10 {print $2}; NR==10 {exit}' </etc/passwd # colon delimited columns
优化是它在打印所需范围的最后一行后退出。
使用了范围模式:
范围模式由两个用逗号分隔的模式组成,格式为“begpat, endpat”。它用于匹配连续输入记录的范围。
https://www.gnu.org/software/gawk/manual/html_node/Ranges.html
模式可以是正则表达式模式或表达式模式。以上使用表达式模式与 NR 进行比较。
我假设用空格分隔列,但提供了一个使用该-F
选项指定不同分隔符的示例。