我有一个包含成千上万行的文件,每一行都以日期开头,例如:
2021-02-22...
但有些奇怪的行并不是以这种方式开始。我的意图是编写一个宏来查找它们,并将它们与上一行连接起来。
我在vim中如何搜索这样的行?
例如,如果我想要在vim中找到下一个匹配的行,我会输入:
/^2021
它会将我带到下一行,该行以“2021”开头。
我想做到这一点,但要查找下一个不匹配的行。
我有一个包含成千上万行的文件,每一行都以日期开头,例如:
2021-02-22...
但有些奇怪的行并不是以这种方式开始。我的意图是编写一个宏来查找它们,并将它们与上一行连接起来。
我在vim中如何搜索这样的行?
例如,如果我想要在vim中找到下一个匹配的行,我会输入:
/^2021
它会将我带到下一行,该行以“2021”开头。
我想做到这一点,但要查找下一个不匹配的行。
:g!/<pattern>/<command>
<command>
在每一行中,不匹配<pattern>
的情况下。在您的情况下,它会像这样::g!/^2021/-j
这里的意思是:
^2021
是你要匹配的模式(pattern),-j
命令先将地址设置为上一行,然后与下一行合并。你可能会觉得以下写法更加直观易懂:
:g!/^2021/norm! kJ
这基本上使用了:-j
的正常模式等价物。
如果您在文件中有几年的时间,请考虑一个简单的交替方案:
:g!/^\(2021\|2020\|2019\)/-j
:g!/^\d\d\d\d-\d\d-\d\d/-j
你不必在这里尝试变得聪明,使用量词和负向回顾等技巧。
参考:
:help :global
:help :range
:help :join
:help :normal
:help k
:help J
:help /^
:help \d
:help /\|
:help /\(
:join
命令与负数范围一起使用是否可行?例如 :g!/^2021/.-1join
,:v/^2021/-j
。 - Peter Rincker:g!/^2021/-j
或者 :v/^2021/-j
都可以,你觉得我应该把它加入我的答案还是你想要发表自己的答案? - romainl:join
命令,它与普通的 j
非常相似。 - Peter Rincker/\v^(2021)@!
对这个搜索的分解:
\v
:使用魔术搜索,将简化vim正则表达式,参见:h \v
。^
:匹配行的开头。(2021)@!
:@!
是负向先行断言,即在行首之后,以下模式不应是2021,括号表示一个正则表达式组。这将查找并选择不以 2021
开头的非空行:
/^[^2]\([^0]\([^2]\([^1]\)\?\)\?\)\?.*
解释:
[^2]
- 期望一个不是 2
的字符\([^<d>]\)\?
,其中 <d>
表示一个数字/^\(\)\@!2021
,但是那并没有起作用。 - Peter Thoeny