当使用sed指定行号时,它将执行指定范围内的指定操作。所以,
sed -n '5,10 p' < file
将从文件中打印第5行到第10行。所以我的理解是,它扫描文件以找到与第一个指定参数(5)匹配的行号,并执行指定的操作,直到达到与第二个参数(10)匹配的行号。但是,当我颠倒范围时,即:
sed -n '10,5 p' < file
它只打印文件中的第10行。那么,我对sed操作方式不正确的假设是什么?是什么导致第10行被打印,因为指定的范围&#39;甚至不是实际的有效范围?
谢谢!
答案 0 :(得分:5)
来自the man page:
可以通过指定以逗号(,)分隔的两个地址来指定地址范围。地址范围匹配从第一个地址匹配的行开始,并一直持续到第二个地址匹配(包含)。
如果第二个地址是正则表达式,那么检查结束匹配将从与第一个地址匹配的行后面的行开始:一个范围总是至少跨越两行(当然,如果输入流结束)
如果第二个地址是小于(或等于)与第一个地址匹配的行的数字,则只匹配一行。
注意第一段中的“包含”一词,然后是第3段中较长的解释。
为什么呢?不要在这里对我们进行形而上学......: - )
答案 1 :(得分:1)
如果指定开始和结束为行号的范围,则结束行号必须大于起始行号。如果结束行号低于或等于起始行号,则该范围仅适用于起始行号。手册页说明了这一点,Peter Bowers想出来了!
我首先想到你想以相反的顺序打印范围内的行,在这种情况下你可以输入tac
:
sed -n '5,10p' file | tac
如果您只想使用(GNU)sed
,可以使用以下脚本:
sed -n '5,10{x;H};${x;s/\n$//p}'
如果当前行在5
和10
之间的范围内,sed将使用x
交换模式缓冲区和保持缓冲区。现在,当前行位于保持缓冲区之上。之后,模式缓冲区(前一个保持缓冲区)将使用H
附加到保持缓冲区。在保持缓冲区中以相反的顺序存储感兴趣的行。在输入$
结束时,我们交换保持缓冲区和模式缓冲区,最后替换换行符,最后使用p
打印它。使用-n
命令行选项禁用正常输出。