Fah*_*tha 10 bash string wildcards patterns
我想对目录中的子目录列表进行操作。考虑:
for x in x86-headers/*/C/populate.sh; do echo $x; done
Run Code Online (Sandbox Code Playgroud)
这给
x86-headers/elf/C/populate.sh
x86-headers/gl/C/populate.sh
x86-headers/gmp/C/populate.sh
x86-headers/gnome2/C/populate.sh
x86-headers/gtk2/C/populate.sh
x86-headers/jni/C/populate.sh
x86-headers/libc/C/populate.sh
Run Code Online (Sandbox Code Playgroud)
但我想要对应于路径第二部分的值
elf,gl, 等。我知道如何去除前导x86-headers.
for x in x86-headers/*/C/populate.sh; do i=${x##x86-headers/}; echo $i; done
Run Code Online (Sandbox Code Playgroud)
这使
elf/C/populate.sh
gl/C/populate.sh
gmp/C/populate.sh
gnome2/C/populate.sh
gtk2/C/populate.sh
jni/C/populate.sh
libc/C/populate.sh
Run Code Online (Sandbox Code Playgroud)
我也知道如何去除路径中的后期术语。即下降一级:
cd x86-headers
for x in */C/populate.sh; do i=${x%%/*}; echo $i; done
Run Code Online (Sandbox Code Playgroud)
给
elf
gl
gmp
gnome2
gtk2
jni
libc
Run Code Online (Sandbox Code Playgroud)
但是,试图将这些结合起来是行不通的。IE
for x in x86-headers/*/C/populate.sh; do i=${${x##x86-headers}%%/*}; echo $i; done
Run Code Online (Sandbox Code Playgroud)
给
bash: ${${x##x86-headers}%%/*}: bad substitution
Run Code Online (Sandbox Code Playgroud)
毫无疑问,这是不正确的语法,但我不知道正确的语法。当然,可能有更好的方法来做到这一点。如果我使用 Python,我会使用 split on/将每个路径分成一个列表,然后选择第二个元素,但我不知道如何在 bash 中执行此操作。
编辑:感谢您的回答。我还应该问,是否可以便携地做到这一点,如果可以,如何做到?
您不能将它们与bash(或 POSIXly)结合使用,您必须分两步完成。
i=${x#*/}; i=${i%%/*}
Run Code Online (Sandbox Code Playgroud)
这可以移植到任何 POSIX shell。如果您需要可移植到 Bourne shell(但是为什么要标记您的问题/bash呢?)以及以防您移植到 Solaris 并被迫使用那里/bin/sh的标准而不是sh那里的标准,或者移植到 20 年前的系统) ,您可以使用这种方法(它也适用于 POSIX shell):
IFS=/; set -f
set x $x
i=$3
Run Code Online (Sandbox Code Playgroud)
(以上是非常罕见的情况之一,其中不加引号的变量是有意义的)。
仅作记录,使用 zsh:
print -rl -- x86-headers/*/C/populate.sh(:h:h:t)
Run Code Online (Sandbox Code Playgroud)
(该吨的的AIL ħ所述的EAD ħ EAD的文件)。
或者对于您的python方法:
x=elf/C/populate.sh
i=${${(s:/:)x}[2]}
Run Code Online (Sandbox Code Playgroud)
参数扩展不允许您嵌套表达式,因此您必须分两步完成,并进行赋值:
i=${x##x86-headers/}
i=${i%%/*}
Run Code Online (Sandbox Code Playgroud)
您可以选择在此处使用数组,但我认为它比上面的 PE 更麻烦:
IFS=/
set -f # Disable globbing in case unquoted $x has globs in it
i=( $x )
set +f
echo "${i[1]}"
Run Code Online (Sandbox Code Playgroud)
然后是使用外部命令的第三个选项。对于简短的文件列表,这通常是效率最低的选项,但随着文件数量的增加,它的扩展性最好:
# For clarity, assume no names have linebreaks in them
find . -name populate.sh | cut -d / -f 3
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10775 次 |
| 最近记录: |