删除两个正则表达式模式之间的字符串

删除两个正则表达式模式之间的字符串

我有一个包含以下内容的文件

..\..\src\modules\core\abc\abc.cpp
..\..\src\modules\core\something\xyz\xyz.cpp
..\..\src\other_modules\new_core\something\pqr\pqr.cpp
..\..\src\other_modules\new_core\something\pqr\abc.cpp

我期待的结果是

..\..\src\abc\abc.cpp
..\..\src\xyz\xyz.cpp
..\..\src\pqr\pqr.cpp
..\..\src\pqr\abc.cpp

我怎样才能使用 sed 实现这一目标?

我无法编写正则表达式来同时捕获两个组。

  1. 初始组 (....\src) - 这在所有行中都是相同的
  2. 变量组 (abc\abc.cpp) 或 (xyz\xyz.cpp) 或 (pqr\pqr.cpp) 或 (pqr\abc.cpp)

答案1

使用 BSDsed或最新版本的 GNU sed(对于旧版本,替换-E-r):

sed -E 's#(.*\\src).*(\\[^\]+\\[^\]+$)#\1\2#' file.txt
  • #用作 的替换 ( s) 命令的分隔符sed,以避免\输入中涉及 s的歧义

  • (.*\\src)从头开始匹配src,并将匹配放入捕获组 1

  • (\\[^\]+\\[^\]+$)匹配直到结束为止有两个 s 的部分\,并放入捕获组 2,.*前面的 this 匹配第一个和第二个捕获组之间的所有内容

  • 在替换中,我们使用了两个捕获的组

POSIX 风格:

sed 's#\(.*\\src\).*\(\\[^\]\+\\[^\]\+$\)#\1\2#' file.txt

例子:

% cat file.txt
..\..\src\modules\core\abc\abc.cpp
..\..\src\modules\core\something\xyz\xyz.cpp
..\..\src\other_modules\new_core\something\pqr\pqr.cpp
..\..\src\other_modules\new_core\something\pqr\abc.cpp

% sed -E 's#(.*\\src).*(\\[^\]+\\[^\]+$)#\1\2#' file.txt
..\..\src\abc\abc.cpp
..\..\src\xyz\xyz.cpp
..\..\src\pqr\pqr.cpp
..\..\src\pqr\abc.cpp

答案2

替代解决方案:

与 GNUgreppaste

grep提取两个模式.*\\src(\\[^\]+){2}$并将它们打印在单独的行上。然后使用组合输出paste

$ grep -oE '.*\\src|(\\[^\]+){2}$' ip.txt | paste -d '' - -
..\..\src\abc\abc.cpp
..\..\src\xyz\xyz.cpp
..\..\src\pqr\pqr.cpp
..\..\src\pqr\abc.cpp

perl

$ perl -pe 's/.*\\src\K.*(?=(\\[^\\]+){2}$)//' ip.txt 
..\..\src\abc\abc.cpp
..\..\src\xyz\xyz.cpp
..\..\src\pqr\pqr.cpp
..\..\src\pqr\abc.cpp

这里,模式之间的文本通过使用积极的环视被.*\\src删除(\\[^\\]+){2}$

答案3

创建一个包含数据的文件

-rwxr-xr-x. 1 sasi   webApp  190 Oct  4 13:42 file.txt

执行以下命令

[sasi@localhost temp]$ sed -E 's#(.*\\src).*(\\[^\]+\\[^\]+$)#\1\2#' file.txt
..\..\src\abc\abc.cpp
..\..\src\xyz\xyz.cpp
..\..\src\pqr\pqr.cpp
..\..\src\pqr\abc.cpp
[sasi@localhost temp]$
[sasi@localhost temp]$
[sasi@localhost temp]$

答案4

为什么用正则表达式来攻击它?路径修改不需要正则表达式;操作系统内核不使用正则表达式来跟踪路径。

使用 Awk,我们只需使用反斜杠作为分隔符,组件就成为字段:

awk 'BEGIN { FS = OFS = "\\" } { print $1, $2, $3, $(NF-1), $NF }'

相关内容