Bash 如何从文件名中提取段?
我有一个具有以下命名方案的文件目录:Bash 如何从文件名中提取段?,bash,shell,Bash,Shell,我有一个具有以下命名方案的文件目录: <project name>-<group name>.txt 如何做到这一点?我正在试验${f###…}和${f%…},但迄今为止没有成功。我不确定它们是否可以组合在一起,因此我可以先省略前缀-,然后再省略后缀.txt我不知道是否可以在一行中实现,但如果按步骤进行,则很容易: for f in *.txt; do base=${f%.txt} projectname=${base%-*} groupname
<project name>-<group name>.txt
如何做到这一点?我正在试验
${f###…}
和${f%…}
,但迄今为止没有成功。我不确定它们是否可以组合在一起,因此我可以先省略前缀-
,然后再省略后缀.txt
我不知道是否可以在一行中实现,但如果按步骤进行,则很容易:
for f in *.txt; do
base=${f%.txt}
projectname=${base%-*}
groupname=${base#*-}
echo project name: $projectname
echo group name: $groupname
done
如果您可以调用外部程序,那么这也可以工作,并且可读性很好
for f in *.txt; do
groupname=$(basename ${f#*-} .txt)
echo group name: $groupname
done
分步做很聪明,很好,谢谢。如果这可以写成一行,那就太棒了,因为我只需要组名。@Bradson如果你使用zsh,你可以嵌套它们:
groupname=${${f%-*}%.sql}
,但是bash不支持这个。谢谢,我没有意识到。改成/bin/bash
我不知道关于bash\u重新匹配的事,但这正是我需要的。谢谢您的回答。@PesaThebash
可执行文件并不总是在/bin
中。使用#之类的东西通常更便于移植/usr/bin/env bash
。(不使用bashism也更具可移植性,但由于避免使用bashism比在每个脚本中多键入8个字符更难,因此它们通常是值得的)。
for f in *.txt; do
groupname=$(basename ${f#*-} .txt)
echo group name: $groupname
done
for file in *-*.txt; do
# shortest match: a-b-c-d.txt => d
[[ $file =~ ([^-]+).txt$ ]] && echo "${BASH_REMATCH[1]}"
# longest match: a-b-c-d.txt => b-c-d
[[ $file =~ -(.+).txt$ ]] && echo "${BASH_REMATCH[1]}"
done