从部分已知的目录中提取子目录路径

从部分已知的目录中提取子目录路径

假设我有以下目录结构:

base/
|
+-- app
|   |
|   +-- main
|       |
|       +-- sub
|           |
|           +-- first
|           |   |
|           |   +-- tib1.ear
|           |   \-- tib1.xml
|           |
|           \-- second
|               |
|               +-- tib2.ear
|               \-- tib2.xml

文件的相对路径ear之一是base/app/main/sub/first/tib1.ear,我如何提取以下子字符串:

  • 该文件,tib1.eartib2.ear
  • 文件之后但不包括该文件的子目录base/app/,即main/sub/firstmain/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.

备择方案

您可能还需要考虑实用程序basenamedirname

$ 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

相关内容