Bash:从路径获取所有路径

时间:2014-08-22 12:25:32

标签: bash shell path traversal dash-shell

说我有路径gui/site/junior/profile.py

我如何得到这个?:

gui
gui/site
gui/site/junior

如果你告诉我如何遍历每条路径,可以获得奖金:D

4 个答案:

答案 0 :(得分:2)

你可以用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,它计算当前记录的字段数。基于此,它从第一个循环到最后一个循环,每次首先打印到该值。

答案 1 :(得分:2)

您可以使用shell的内置拆分工具。 IFS指定要拆分的内容。

oldIFS=$IFS
IFS=/
set -f
set -- $path
set +f
IFS=$oldIFS
for component in "$@"; do
    echo "$component"
done

这可以通过多种方式进行重构,但我希望对IFS进行更改以仅控制实际的拆分。

使用set将字符串拆分为位置参数有点模糊,但值得深入了解。

如果最初没有设置IFS,你应该小心谨慎,但我对此不屑一顾。

答案 2 :(得分:2)

简短的回答:

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/

答案 3 :(得分:1)

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==