英文:
bash: How to extract any dirname from the path
问题
想要提取 .../users/**THIS**/random/....
后的目录名(即 upload、upload2 或 upload3),您可以尝试以下方式:
file=./home/mnt/users/upload/random/reports/on/a/server.md
echo ${file%/*} # 这将输出完整路径,如:./home/mnt/users/upload/random/reports/on/a
echo $(basename $(dirname $(dirname $file))) # 这将输出所需的目录名,如:upload
这两行代码中,${file%/*}
用于截取最后一个斜杠 /
之前的部分,然后 $(basename $(dirname $(dirname $file)))
用于提取倒数第三个目录的名称,即您所需的目录名。
英文:
So, I have a few basename such as
./home/mnt/users/upload/random/reports/on/a/server.md
./home/mnt/users/upload2/random/reports/on/a/server.md
./home/mnt/users/upload3/random/reports/on/a/server.md
I want to extract the dirname (look for THIS) after the .../users/**THIS**/random/....
so the output should be either upload, upload2 or upload3
tried with few options such as
file=./home/mnt/users/upload/random/reports/on/a/server.md
echo ${file%/*}
echo $(basename $(dirname $(dirname $file)))
how can I achieve that?
答案1
得分: 2
sed提取具有父目录和子目录/users/
和/random/
的目录名称的一种方法:
sed -En 's:.*/users/([^/]+)/random/.*::p';
其中:
-E
- 启用扩展的正则表达式支持(包括捕获组)-n
- 抑制默认打印模式空间内容.*/users/
- 匹配以正则表达式.*/users/
开头的部分([^/]+)
- (捕获组 #1) - 匹配任何非/
字符/random/.*
- 匹配以正则表达式/random/.*
结尾的部分\1:p
- 打印捕获组 #1 的内容
进行测试:
for fname in './home/mnt/users/upload/random/reports/on/a/server.md' './home/mnt/users/upload2/random/reports/on/a/server.md' './home/mnt/users/upload3/random/reports/on/a/server.md';
do
echo "############ $fname"
sed -En 's:.*/users/([^/]+)/random/.*::p' <<< "${fname}"
done
这将生成以下结果:
############ ./home/mnt/users/upload/random/reports/on/a/server.md
upload
############ ./home/mnt/users/upload2/random/reports/on/a/server.md
upload2
############ ./home/mnt/users/upload3/random/reports/on/a/server.md
upload3
英文:
One sed
approach to extract the name of the directory that has parent and child directories of /users/
and /random/
, respectively:
sed -En 's:.*/users/([^/]+)/random/.*::p'
Where:
-E
- enable extended regex support (and capture groups)-n
- suppress default printing of pattern space.*/users/
- match on leading regex.*/users/
([^/]+)
- (capture group #1) - match on anything not a/
/random/.*
- match on trailing regex/random/.*
\1:p
- print contents of capture group #1
Taking for a test drive:
for fname in './home/mnt/users/upload/random/reports/on/a/server.md' './home/mnt/users/upload2/random/reports/on/a/server.md' './home/mnt/users/upload3/random/reports/on/a/server.md'
do
echo "############ $fname"
sed -En 's:.*/users/([^/]+)/random/.*::p' <<< "${fname}"
done
This generates:
############ ./home/mnt/users/upload/random/reports/on/a/server.md
upload
############ ./home/mnt/users/upload2/random/reports/on/a/server.md
upload2
############ ./home/mnt/users/upload3/random/reports/on/a/server.md
upload3
答案2
得分: 0
使用bash
的正则表达式操作符(=~
):
[[ $pathname =~ /users/([^/]*) ]] && echo "${BASH_REMATCH[1]}"
英文:
With bash
's regular expression operator (=~
):
[[ $pathname =~ /users/([^/]*) ]] && echo "${BASH_REMATCH[1]}"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论