我正在使用grep
和sed
解决一堆文本字符串,其中我只希望 stdout
在之后打印数据package:
,并以文件夹名称结尾,结尾没有 /
。
例如:
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
我没有得到想要的确切输出,因此将不胜感激。
PS:我正在学习grep
和sed
只是为了好玩。
答案 0 :(得分: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
的后向引用代替,只需丢弃不必要的组即可。
希望这会有所帮助。
答案 1 :(得分:1)
这可能对您有用(GNU sed):
sed -n 's#^package:\(.*\)/.*#\1#p' file
由于这可能是过滤操作,请使用-n
选项显式打印结果。 regexp从替换命令中的^
开始,该命令将package:
锚定到行的开头,并使用.*
贪婪地消耗行的其余部分。但是,它尝试匹配的下一个字符是/
,因此正则表达式引擎回溯以找到它,然后后面的.*
再次吞噬了该行的其余部分。用引号括起来的括号\(...\)
捕获了正则表达式的这一部分,并用\1
表示在替代命令的RHS中,称为反向引用。替换命令末尾的p
标志显式地显示修改后的行的当前状态。
使用替代命令,程序员可以选择其定界符。在文档中,命令通常写为s/LHS/RHS/flags
,其中定界符为/
,但可以是上述解决方案#
中选择的任何字符,以减少对{{1}的引用。 }字符,左侧为LHS = regexp,右侧为RHS =替换,标志=其他操作,例如/
表示在行/文件中全局替换,g
表示在当前状态下打印行成功的替代品(还有其他参考sed文档。