假设我有以下目录结构:
base/
|
+-- app
| |
| +-- main
| |
| +-- sub
| |
| +-- first
| | |
| | +-- tib1.ear
| | \-- tib1.xml
| |
| \-- second
| |
| +-- tib2.ear
| \-- tib2.xml
文件的相对路径ear
之一是base/app/main/sub/first/tib1.ear
,我如何提取以下子字符串:
- 该文件,
tib1.ear
或tib2.ear
- 文件之后但不包括该文件的子目录
base/app/
,即main/sub/first
或main/sub/second
所有的目录名称都是动态生成的,所以我不知道它们base/app/
,因此不能简单地使用已知子字符串的长度并使用cut
它们来截断它们;但我知道一旦文件名已知,这怎么可能。我只是觉得有一种比根据其他结果的长度切割和连接一堆字符串更简单的方法。
我记得看到过一些与此类似的正则表达式魔法。它涉及用反斜杠分割和连接子字符串,但遗憾的是,我不记得他们是如何做到的,也不记得我在哪里看到它并再次查找它。
答案1
让我们从您的文件名开始:
$ f=base/app/main/sub/first/tib1.ear
要提取基本名称:
$ echo "${f##*/}"
tib1.ear
要提取目录名称的所需部分:
$ g=${f%/*}; echo "${g#base/app/}"
main/sub/first
${g#base/app/}
和${f##*/}
是例子前缀去除。 ${f%/*}
是一个例子后缀去除。
文档
从man bash
:
${parameter#word} ${parameter##word} Remove matching prefix pattern. The word is expanded to produce a pattern just as in pathname expansion. If the pattern matches the beginning of the value of parameter, then the result of the expansion is the expanded value of parameter with the shortest matching pattern (the ``#'' case) or the longest matching pattern (the ``##'' case) deleted. If parameter is @ or *, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with @ or *, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list. ${parameter%word} ${parameter%%word} Remove matching suffix pattern. The word is expanded to produce a pattern just as in pathname expansion. If the pattern matches a trailing portion of the expanded value of parameter, then the result of the expansion is the expanded value of parameter with the shortest matching pattern (the ``%'' case) or the longest matching pattern (the ``%%'' case) deleted. If parameter is @ or *, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable sub‐ scripted with @ or *, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list.
备择方案
您可能还需要考虑实用程序basename
和dirname
:
$ basename "$f"
tib1.ear
$ dirname "$f"
base/app/main/sub/first
答案2
创建测试文件
mkdir -p base/app/main/sub/{first,second}
touch base/app/main/sub/first/tib1.{ear,xml}
touch base/app/main/sub/second/tib2.{ear,xml}
使用bash查找ear文件
shopt -s globstar nullglob
ear_files=( base/**/*.ear )
printf "%s\n" "${ear_files[@]}"
base/app/main/sub/first/tib1.ear
base/app/main/sub/second/tib2.ear
迭代数组并使用 John1024 的答案从每个路径中提取必要的信息。
for f in "${ear_files[@]}"; do ...; done