所以我对我目前所说的“高级”正则表达式还很陌生,请原谅我,这对你们来说可能真的很容易,但我需要指出正确的方向,因为现在我正在挣扎。
我爬行了论坛和网站(包括:http://www.grymoire.com/Unix/Sed.html)并且我找不到我正在寻找的东西,或者至少找不到相反的东西,所以我然后反转它并获得我想要的标准输出。
数据(标准输入)如下所示:
C:\Users\Maison\Documents\AutoCad_dir
True
False
0
1
User
Group
Everyone
Full Access
S-I-D
C:\Users\Maison\Documents
True
False
0
1
User
Group
Everyone
Full Access
S-I-D
我想做的是使用正则表达式,删除每一行4 目录 或者更多以及接下来的 10 行(包括 CR \r)。
所以剩下的看起来像这样:
C:\Users\Maison\Documents
True
False
0
1
User
Group
Everyone
Full Access
S-I-D
笔记:卷标 (C:) 不是恒定的,我正在使用的数据不是绝对的。
当然,在我掌握的实际数据中,还有很多与我要删除的类似的线条。
到目前为止我拥有的最好的是:
sed '/pattern/I,+11 d' infile
但我无法想出一个逻辑模式,到目前为止我想出的每个模式都会删除每一行,无论目录数量如何。
我不愿意问,但这最终会让我更好地理解 RegEx 和 GNU sed。
答案1
例子:
sed '/^[A-Z]:\\\([^\\]\+\\\)\{3,\}/,+10d' test.txt
如果您使用扩展正则表达式(指定-r
为sed
),那么表达式将变得更容易阅读,因为您只需转义\
:
sed -r '/^[A-Z]:\\([^\\]+\\){3,}/,+10d' test.txt
值得注意的部分是([^\\]+\\){3,}
,括号中的模式告诉它匹配除 之外的任何字符的 1 个或多个实例/
,然后跟随一个/
. {3,} 告诉它括号中的模式必须至少匹配 3 次才能匹配。
答案2
使用awk
(因为问题是使用awk标签):
$ awk -F '\\' 'NF > 4 { skip = 11 } --skip < 0 { print }' file.in
C:\Users\Maison\Documents
True
False
0
1
User
Group
Everyone
Full Access
S-I-D
这将每一行视为一条\
分隔记录。如果记录中的字段数大于 4,我们通过设置跳过该记录和接下来的 10 行输入skip = 11
。然后,该变量针对每行输入递减,如果其值为负数(这意味着我们已经跳过了我们想要跳过的行),我们将打印该行。
该脚本可以缩短为
$ awk -F '\\' 'NF > 4 { skip = 11 } --skip < 0' file.in
该脚本的两个版本都会失败(产生错误的输出)如果每个块的第一行以外的任何其他行包含四个\
或更多。