【发布时间】:2020-08-21 20:05:42
【问题描述】:
输入文本是:
Lines_with_no_search_string_1
...,"service_id":222,"...1
...,"service_id":111,"...2
Lines_with_no_search_string_2
...,"service_id":111,"...3
...,"service_id":222,"...4
Lines_with_no_search_string_3
...,"service_id":222,"...5
Lines_with_no_search_string_4
...,"service_id":111,"...6
Lines_with_no_search_string_5
注意事项:
- “...”是不包含“service_id”的随机字符串。 (“...”后面的数字仅用于识别线序!)
- “Lines_with_no_search_string”是一行或多行不包含“service_id”的行。
- 最多只有 2 行包含“service_id”,即包含“111”和“222”的连续行。
标准:
- 不包含“service_id”的行
- 打印出来(行号相同)。
- 包含“service_id”的单行
- 如果为“111”,则按原样打印(行号相同)。
- 如果为“222”,则按原样打印,并在行首插入字符串“NONE”(行号相同)。
- 包含“service_id”的连续两行
- 如果先出现“111”,则按原样打印两行(行号相同)。
- 如果“222”在前,则以相反的顺序打印,即先打印“111”和“222”(与原始行号相比,行号相反)。
想要的输出是:
Lines_with_no_search_string_1
...,"service_id":111,"...2 (*)
...,"service_id":222,"...1 (*)
Lines_with_no_search_string_2
...,"service_id":111,"...3
...,"service_id":222,"...4
Lines_with_no_search_string_3
"NONE"...,"service_id":222,"...5 (*)
Lines_with_no_search_string_4
...,"service_id":111,"...6
Lines_with_no_search_string_5
(*) 显示已修改的行。
我想使用“sed”的原因是我有一个很长的命令行导致上述输入,我更喜欢继续使用管道(“|”)来获得最终输出。 如果有所谓的单行命令,除了“sed”之外还有其他命令可以提供所需的输出,我很乐意使用它。
我在不同的“sed”组合上花了很多时间,但没有弄对。
我的最后一种方法是基于以下替换“\n”的代码:
sed ':a;N;$!ba;s/\n/some_string/g' # Note: for csh/tcsh, "!" needs to be escaped.
我尝试将两个连续的行(当 222 行后跟 111 行)放在“\1”和“\2”中,并将它们反转:
sed ':a;N;$!ba;s/\(.*[^2][^2][^2]*222.*\)\n\(.*[^1][^1][^1]*111.*\)/\2\n\1/g'
但它并没有像我想的那样工作:
...,"service_id":111,"...6
Lines_with_no_search_string5
Lines_with_no_search_string1
...,"service_id":222,"...1
...,"service_id":111,"...2
Lines_with_no_search_string2
...,"service_id":111,"...3
...,"service_id":222,"...4
Lines_with_no_search_string3
...,"service_id":222,"...5
Lines_with_no_search_string4
我现在已经意识到,我的方法所基于的解决方案会遍历整个文件。 这就是上面输出乱码的原因。
如果有人能提出解决方案,请不胜感激。
【问题讨论】:
-
欢迎来到 Stack Overflow。 SO 是面向专业和热情的程序员的问答页面。请在您的问题中添加您自己的代码。您应该至少展示自己为解决这个问题所做的研究。
-
请使用tour 并阅读How to Ask。您应该提供minimal reproducible example。