需要从包含分隔符的文件路径字符串中提取子字符串

Sou*_*jee 6 command-line bash scripts text-processing

执行 shell 脚本时,输入字符串类似于:

test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class
Run Code Online (Sandbox Code Playgroud)

我如何提取: test1/test2/Test.jar[即子字符串直到第一次出现'.jar'分隔符,包括],在shell脚本中

我怎样才能做到这一点?我不想使用 cut 然后在末尾附加“.jar”。

谢谢

Eli*_*gan 7

此外sed,您还可以选择grep为此使用 PCRE 正则表达式^.*?\.jar

grep -oP '^.*?\.jar' <<<"test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class"
Run Code Online (Sandbox Code Playgroud)

这仅打印匹配 ( -o),使用PCRE ( -P),并匹配以下文本:

  • 从行首 ( ^) 开始,并且
  • 包含任意字符 ( .),任意次数但延迟匹配 ( *?),
  • 后跟一个文字.字符 ( \.) 和jar( jar)

使用惰性量词 *?而不是通常的贪婪量词*会导致grep匹配尽可能少的字符。

  • 没有它(并使用贪婪量词代替),grep只要匹配以 结尾,就会匹配尽可能多的字符,如果有多个字符.jar,它将无法在第一个 之后停止.jar
  • -P标志是必需的,因为grep在 Ubuntu 上支持的正则表达式方言中,PCRE 是支持 laziness 的方言。(这种方言Perl 中的正则表达式方言非常相似。)


αғs*_*нιη 6

你可以sed像下面这样使用:

sed 's/\(\.jar\).*/\1/' <<<"test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class" 
Run Code Online (Sandbox Code Playgroud)

或者通过awk命令:

awk -F'\\.jar' '{print $1".jar"}' <<<"test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class"
Run Code Online (Sandbox Code Playgroud)

输出是:

test1/test2/Test.jar
Run Code Online (Sandbox Code Playgroud)


Dav*_*ter 6

既然你提到了 shell 脚本,我提出了一个简单的、纯粹基于 shell 的解决方案:

s='test1/test2/Test.jar/Test2.jar/com/test/ui/GI.class'
echo "${s%%.jar*}.jar"
Run Code Online (Sandbox Code Playgroud)

参数扩展 %%消除了最长后缀,随后的匹配glob模式 .jar*(相对于%其中最短的后缀相匹配)。