说我有路gui/site/junior/profile.py
我如何得到这个?:
gui
gui/site
gui/site/junior
如果您告诉我如何遍历每条路径,则可以奖励:D
说我有路gui/site/junior/profile.py
我如何得到这个?:
gui
gui/site
gui/site/junior
如果您告诉我如何遍历每条路径,则可以奖励:D
您可以使用 shell 的内置拆分工具。IFS
指定要拆分的内容。
oldIFS=$IFS
IFS=/
set -f
set -- $path
set +f
IFS=$oldIFS
for component in "$@"; do
echo "$component"
done
这可以通过多种方式进行重构,但我希望更改IFS
为仅管理实际拆分。
set
将字符串拆分为位置参数的用法有点晦涩,但值得了解。
如果它最初是未设置的,您应该适当地注意取消IFS
设置,但我对此有所了解。
一个破折号的答案:
path="gui/site with spaces/junior/profile.py"
oldIFS=$IFS
IFS=/
set -- $(dirname "$path")
IFS=$oldIFS
accumulated=""
for dir in "$@"; do
accumulated="${accumulated}${dir}/"
echo "$accumulated"
done
gui/
gui/site with spaces/
gui/site with spaces/junior/
您可以使用 awk 循环:
awk 'BEGIN{FS=OFS="/"}
{ for (i=1; i<=NF; i++) {
for (j=1; j<i; j++)
printf "%s/", $j
printf "%s\n", $i
}
}' <<< "gui/site/junior/profile.py"
视为一个班轮:
$ awk 'BEGIN{FS=OFS="/"}{for (i=1; i<=NF; i++) { for (j=1; j<i; j++) printf "%s%s", $j, OFS; printf "%s\n", $i}}' <<< "gui/site/junior/profile.py"
gui
gui/site
gui/site/junior
gui/site/junior/profile.py
这利用了NF
,它计算当前记录有多少个字段。基于此,它从第一个循环到最后一个,每次首先打印到该值。
Perl 变体:
perl -F/ -nlE 'say join("/",@F[0..$_])||"/"for(0..$#F-1)' <<< "gui/site with spaces/junior/profile.py"
生产
gui
gui/site with spaces
gui/site with spaces/junior
如果你有 NULL 分隔路径名,你可以添加0
到参数:
perl -F/ -0nlE 'say join("/",@F[0..$_])||"/"for(0..$#F-1)'
^
例如从
printf "/some/path/name/here/file.py\0" | perl -F/ -nlE 'say join("/",@F[0..$_])||"/"for(0..$#F-1)'
# ^^
生产
/
/some
/some/path
/some/path/name
/some/path/name/here
为了迭代路径,您可以使用下一个:
origpath="some/long/path/here/py.py"
do_something() {
local path="$1"
#add here what you need to do with the partial path
echo "Do something here with the ==$path=="
}
while read -r part
do
do_something "$part"
done < <(perl -F/ -nlE 'say join("/",@F[0..$_])||"/"for(0..$#F-1)' <<< "$origpath")
它产生:
Do something here with the ==some==
Do something here with the ==some/long==
Do something here with the ==some/long/path==
Do something here with the ==some/long/path/here==