我有一个包含许多列的 txt 文件(如下所示),我需要获取第二列位置到第三列位置之间包含的行。
1 10385389 10385390 . 21
1 10385390 10385391 . 22
1 10385391 10385392 . 22
1 10385392 10385393 . 21
1 10385393 10385394 . 22
1 10385394 10385395 . 25
1 10385395 10385396 . 25
1 10385396 10385397 . 25
1 10385397 10385398 . 25
1 10385398 10385399 . 25
以这个例子为例,假设我想从 10385391 到 10385397 中选择所需的输出
1 10385391 10385392 . 22
1 10385392 10385393 . 21
1 10385393 10385394 . 22
1 10385394 10385395 . 25
1 10385395 10385396 . 25
1 10385396 10385397 . 25
奖励:同样重要的是,如果没有找到起始位置,则取而代之的是结束位置。在提供的示例中,这不会发生,因为有一个相关的系列,但万一我得到这样的文件
1 10385389 10385390 . 21
1 10385391 10385392 . 22
1 10385392 10385393 . 21
1 10385393 10385394 . 22
我想避免错误是用户引入了 10385390,而在第二列中找不到该错误。
答案1
启动和停止条件可以直接在 AWK 中处理:
awk '$2 == "10385391",$3 == "10385397"'
这将输出以第二个字段为“10385391”的行开始、以第三个字段为“10385397”的行结束的所有行。
为了处理更灵活的条件,我们可以考虑您想要第一个和第二个字段的值在 10385391 和 10385397 之间的任何行:
awk '$2 >= 10385391 && $3 <= 10385397'
如果输入包含多组符合条件的行,则它们都将被输出。
答案2
命令
awk '$2 == "10385391" { f=1 } $3 == "10385397" { f=0; print }; f' filename
10385391
它在第二列中查找,并f
在找到时设置为 1。这会导致f
打印该行以及所有值为 1 的行(这是通过代码f
中的尾随完成的awk
)。每当第三列为 时10385397
,f
都会重置为零以避免打印更多行,并打印当前行。
输出
1 10385391 10385392 . 22
1 10385392 10385393 . 21
1 10385393 10385394 . 22
1 10385394 10385395 . 25
1 10385395 10385396 . 25
1 10385396 10385397 . 25
答案3
awk -v begin=10385390 -v end=10385397 '($2 >= begin && $2 <= end) || ($3 >= begin && $3 <= end) || (begin <= $2 && end >= $3)' file
这将返回范围与[$2,$3]
给定范围重叠的任何行[begin,end]
。
对于给定的数据,这将返回
1 10385389 10385390 . 21
1 10385390 10385391 . 22
1 10385391 10385392 . 22
1 10385392 10385393 . 21
1 10385393 10385394 . 22
1 10385394 10385395 . 25
1 10385395 10385396 . 25
1 10385396 10385397 . 25
1 10385397 10385398 . 25
仅获取范围[$2,$3]
为里面给定[begin,end]
范围:
awk -v begin=10385390 -v end=10385397 '$2 >= begin && $3 <= end' file