删除所有与模式不匹配的行
Delete all lines which don't match a pattern
我正在寻找一种方法来删除所有不遵循特定模式的行(来自 txt 文件)。
我需要保留以下行的模式:
x//x/x/x/5/x/
x
可以是任意数量的字符、数字或特殊字符。
5
始终是字母数字的组合 - 5 个字符 - 例如 Xf1Lh,始终出现在第 5 个正斜杠之后。
/
是实际的正斜杠。
输入:
abc//a/123/gds:/4AdFg/f3dsg34/
y35sdf//x/gd:df/j5je:/x/x/x
yh//x/x/x/5Fsaf/x/
45wuhrt//x/x/dsfhsdfs54uhb/
5ehys//srt/fd/ab/cde/fg/x/x
期望的输出:
abc//a/123/gds:/4AdFg/f3dsg34/
yh//x/x/x/5Fsaf/x/
grep
根据正则表达式选择行,而您的 x//x/x/x/5/x/
只需稍作改动即可使其成为正则表达式:
$ grep -E '.*//.*/.*/.*/[[:alnum:]]{5}/.*/' file
abc//a/123/gds:/4AdFg/f3dsg34/
yh//x/x/x/5Fsaf/x/
解释:
"x could be any amount of characters, numbers or special characters"。在 .*
的正则表达式中,.
表示任何字符,*
表示零个或多个前面的字符(在本例中为 .
)。
“5 始终是字母数字 - 5 个字符的组合”。在 POSIX 正则表达式中,[[:alnum:]]
表示任何字母数字字符。 {5}
表示前五项。 [[:alnum:]]
是 unicode 安全的。
可能的改进
一个问题是如何解释 x
。在上面,x
被允许是任何字符。然而,正如 triplee 指出的那样,另一个合理的解释是 x
应该是除 /
之外的任何字符。在那种情况下:
grep -E '[^/]*//[^/]*/[^/]*/[^/]*/[[:alnum:]]{5}/[^/]*/' file
此外,我们可能希望此正则表达式仅匹配 完整 行。在那种情况下,我们可以用 ^
和 $
包围正则表达式,或者我们可以使用 grep 的 -x
选项:
grep -xE '[^/]*//[^/]*/[^/]*/[^/]*/[[:alnum:]]{5}/[^/]*/' file
您可以使用 -P
选项来扩展 perl 支持,例如
grep -P "^(?:[^/]*/){5}[A-Za-z0-9]{5}/(?:/|$)" input
输出
abc//a/123/gds:/4AdFg/f3dsg34/
yh//x/x/x/5Fsaf/x/
正则表达式分解
^ #Start of line
(?: #Non capturing group
[^/]* #Match anything except /
/ #Match / literally
){5} #Repeat this 5 times
[A-Za-z0-9]{5} #Match alphanumerics. You can use \w if you want to allow _ along with [A-Za-z0-9]
(?: #Non capturing group
/ #Next character should be /
| #OR
$ #End of line
)
我正在弄清楚如何在 awk 中与其他答案同时进行,并想出了:
awk -F/ 'BEGIN{OFS=FS}==""&&~/[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]/&&NF=8'
我使用的 awk 不支持 {5}
regexp frob。
使用 sed 和就地编辑 删除所有不遵循特定模式的行(来自 txt 文件):
$ sed -i.bak -n "/.*\/\/.*\/.*\/.*\/[a-zA-Z0-9]\{5\}\/.*\//p" test.in
$ cat test.in
abc//a/123/gds:/4AdFg/f3dsg34/
yh//x/x/x/5Fsaf/x/
-i.bak
就地编辑创建一个 test.in.bak 备份文件,-n
安静,不打印不匹配的输出
和 ".../p"
打印匹配项。
我正在寻找一种方法来删除所有不遵循特定模式的行(来自 txt 文件)。
我需要保留以下行的模式:
x//x/x/x/5/x/
x
可以是任意数量的字符、数字或特殊字符。
5
始终是字母数字的组合 - 5 个字符 - 例如 Xf1Lh,始终出现在第 5 个正斜杠之后。
/
是实际的正斜杠。
输入:
abc//a/123/gds:/4AdFg/f3dsg34/
y35sdf//x/gd:df/j5je:/x/x/x
yh//x/x/x/5Fsaf/x/
45wuhrt//x/x/dsfhsdfs54uhb/
5ehys//srt/fd/ab/cde/fg/x/x
期望的输出:
abc//a/123/gds:/4AdFg/f3dsg34/
yh//x/x/x/5Fsaf/x/
grep
根据正则表达式选择行,而您的 x//x/x/x/5/x/
只需稍作改动即可使其成为正则表达式:
$ grep -E '.*//.*/.*/.*/[[:alnum:]]{5}/.*/' file
abc//a/123/gds:/4AdFg/f3dsg34/
yh//x/x/x/5Fsaf/x/
解释:
"x could be any amount of characters, numbers or special characters"。在
.*
的正则表达式中,.
表示任何字符,*
表示零个或多个前面的字符(在本例中为.
)。“5 始终是字母数字 - 5 个字符的组合”。在 POSIX 正则表达式中,
[[:alnum:]]
表示任何字母数字字符。{5}
表示前五项。[[:alnum:]]
是 unicode 安全的。
可能的改进
一个问题是如何解释 x
。在上面,x
被允许是任何字符。然而,正如 triplee 指出的那样,另一个合理的解释是 x
应该是除 /
之外的任何字符。在那种情况下:
grep -E '[^/]*//[^/]*/[^/]*/[^/]*/[[:alnum:]]{5}/[^/]*/' file
此外,我们可能希望此正则表达式仅匹配 完整 行。在那种情况下,我们可以用 ^
和 $
包围正则表达式,或者我们可以使用 grep 的 -x
选项:
grep -xE '[^/]*//[^/]*/[^/]*/[^/]*/[[:alnum:]]{5}/[^/]*/' file
您可以使用 -P
选项来扩展 perl 支持,例如
grep -P "^(?:[^/]*/){5}[A-Za-z0-9]{5}/(?:/|$)" input
输出
abc//a/123/gds:/4AdFg/f3dsg34/
yh//x/x/x/5Fsaf/x/
正则表达式分解
^ #Start of line
(?: #Non capturing group
[^/]* #Match anything except /
/ #Match / literally
){5} #Repeat this 5 times
[A-Za-z0-9]{5} #Match alphanumerics. You can use \w if you want to allow _ along with [A-Za-z0-9]
(?: #Non capturing group
/ #Next character should be /
| #OR
$ #End of line
)
我正在弄清楚如何在 awk 中与其他答案同时进行,并想出了:
awk -F/ 'BEGIN{OFS=FS}==""&&~/[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]/&&NF=8'
我使用的 awk 不支持 {5}
regexp frob。
使用 sed 和就地编辑 删除所有不遵循特定模式的行(来自 txt 文件):
$ sed -i.bak -n "/.*\/\/.*\/.*\/.*\/[a-zA-Z0-9]\{5\}\/.*\//p" test.in
$ cat test.in
abc//a/123/gds:/4AdFg/f3dsg34/
yh//x/x/x/5Fsaf/x/
-i.bak
就地编辑创建一个 test.in.bak 备份文件,-n
安静,不打印不匹配的输出
和 ".../p"
打印匹配项。