下面是示例.log文件(这里可以有更多行)
2022 User abc (iii)
2023 defaa <party> ttt
2222221 User def (bbb)
20222 defaa <accoun> ttt
2222 User dddd (aaa)
3333 defaa <hahaha> jmd我想在User和ttt之间选择行
请注意,这些类似于日志的5-7行,这个日志中可以有更多由User和ttt组成的行。
因此,我想知道一种获取User和ttt之间所有行的方法,即使它们在文件中被重复
文本User和ttt并不总是在连续的行上
预期产出:
abc (iii)
2023 defaa <party>
def (bbb)
20222 defaa <accoun> 在筑巢的情况下,如下所示:
2022 User abc (iii)
2222221 User def (bbb)
20222 defaa <accoun> ttt
2023 defaa <party> ttt预期产出:
def (bbb)
20222 defaa <accoun>User & ttt永远不会在同一条线上
发布于 2023-03-23 10:29:10
使用sed,您可以选择一个地址范围fron User到ttt,并在保持空间中收集:
sed '/User/,/ttt/!d;H;/User/h;/ttt/!d;x;s/.*User //;s/ttt.*//' yourfile不合标准的解释:
/User/,/ttt/在从User到下一个ttt的范围内选择行(就像嵌套的情况所要求的那样);这个选择由!和d选择。因此,此步骤移除此范围之外的所有行。不幸的是,从最后一个User到文件末尾的最后一个部分没有被删除,所以我们需要一种方法来消除这个问题:H将所有行附加到保持空间,而/User/h则将带有User的行复制到保持空间,因此保持空间包含从User到当前行的所有行。这样,新的User行就会覆盖之前的所有内容,就像嵌套的情况所期望的那样。/ttt/!d在没有ttt的情况下停止对所有行的执行,因此我们不会生成任何输出,直到我们在保存空间中收集了User' to‘t`中的所有内容。x改变缓冲区,让这些行从我们的模式空间中的保持空间中,User将所有内容删除到s/.*User //中ttt和s/ttt.*//开始删除所有内容发布于 2023-03-23 13:21:38
使用GNU来表示多个字符的RS、RT和\s是[:space:]的缩写,您可能需要这样做:
$ awk -v RS='\\s*ttt' 'RT && sub(/.*User\s*/,"")' file
abc (iii)
2023 defaa <party>
def (bbb)
20222 defaa <accoun>如果不希望在User和ttt上允许部分匹配,那么在它们周围添加单词边界:
awk -v RS='\\s*\\<ttt\\>' 'RT && sub(/.*\<User\>\s*/,"")' filehttps://unix.stackexchange.com/questions/740690
复制相似问题