使用GREP和SED获得精确的模式匹配

问题描述 投票:0回答:2

大家好,

我正在使用GREPSED解决一堆文本字符串,其中我只希望stdoutpackage:之后打印数据,并以文件夹名称结尾没有结尾/

例如:

data/dataapp/com.android.chrome-DeX_54==
System/app/Keychain
vendor/app/NlpService

这是示例...

package:data/app/com.android.chrome-DeX_54==/base.apk=com.android.chrome
package:data/dataapp/ExactCalculator/ExactCalculator.apk=com.android.calculator2
package:data/hw_init/cust/app/Email/Email.apk=com.android.email
package:system/app/KeyChain/KeyChain.apk=com.android.keychain
package:system/delapp/WallpaperBackup/WallpaperBackup.apk=com.android.wallpaperbackup
package:system/framework/framework-res.apk=android
package:system/priv-app/CIT/CIT.apk=com.ontim.cit
package:vendor/app/NlpService/NlpService.apk=com.mediatek.nlpservice

我没有得到我想要的确切输出,因此将不胜感激。

P.S:我正在学习GREPSED,只是为了好玩。

string bash shell sed grep
2个回答
1
投票

请您尝试:

grep -Po '(?<=package:).+(?=/[^/]*$)' input.txt

结果:

data/app/com.android.chrome-DeX_54==
data/dataapp/ExactCalculator
data/hw_init/cust/app/Email
system/app/KeyChain
system/delapp/WallpaperBackup
system/framework
system/priv-app/CIT
vendor/app/NlpService
  • -P选项启用Perl兼容的正则表达式。
  • -o选项告诉grep仅打印匹配的子字符串。
  • 模式(?<=package:)positive lookbehind assertion,匹配的子字符串不包含在grep -o的输出中。
  • 模式(?=/[^/]*$)也是positive lookahead assertion

sed替代为:

sed 's#\(^package:\)\(.\+\)\(/[^/]*$\)#\2#' input.txt

sed -E 's#(^package:)(.+)(/[^/]*$)#\2#' input.txt

后者将更清晰。

您将看到positive lookarounds可以通过丢弃不必要的组而被sed的后向引用代替。

希望这会有所帮助。


0
投票

这可能对您有用(GNU sed):

sed -n 's#^package:\(.*\)/.*#\1#p' file

由于这可能是过滤操作,请使用-n选项显式打印结果。 regexp在替换命令中以^开头,该命令将package:锚定到行的开头,并使用.*贪婪地消耗行的其余部分。但是,它尝试匹配的下一个字符是/,因此正则表达式引擎回溯以找到它,然后下一个.*再次吞噬了该行的其余部分。用引号引起的括号(\(...\))捕获了正则表达式的这一部分,并在替代命令的RHS中用称为后引用的\1表示。替换命令末尾的p标志明确显示修改后的行处于其当前状态。

N.B。使用替代命令,程序员可以选择其定界符。在文档中,命令通常写为s/LHS/RHS/flags,其中分隔符为/,但可以是任何字符,如在上述解决方案中一样,选择#是为了减少对/字符的引用,LHS = regexp左侧,RHS =替换,标志=附加操作,例如g表示在行/文件中全局替换,p表示在成功替换后以当前状态打印该行(还有其他内容请参见sed文档。) >

© www.soinside.com 2019 - 2024. All rights reserved.