我有一个文件的明确路径:
/aaa/bbb/ccc/ddd/eee/fff.txt
我需要cd /aaa/bbb
对 执行操作ccc/ddd/eee/fff.txt
。
我明白了第一点:
df_test=/aaa/bbb/ccc/ddd/eee/fff.txt
cd $( echo ${df_test} | awk -F/ '{print "/"$2"/"$3}' )
然后,我如何砍掉路径中的前两步,并对其余部分进行操作?此外,我不会提前知道这些文件有多深。我可能有
/aaa/bbb/ccc/ddd.txt
/aaa/bbb/ccc/ddd/eee/fff.txt
/aaa/bbb/ccc/ddd/eee/fff/ggg/hhh/iii.txt
我只需要将目录更改为/aaa/bbb,并对剩余的相对路径进行操作。
答案1
在标准外壳中:
$ path=/aaa/bbb/ccc/ddd/eee/fff.txt
$ tail="${path#/*/*/}"
$ head="${path%/$tail}"
$ echo "$head" "$tail"
/aaa/bbb ccc/ddd/eee/fff.txt
"${path#/*/*/}"
path
是但删除了(最短)前导部分匹配的值/*/*/
,即您的尾部部分。然后"${path%/$tail}"
用path
斜线去除尾部。
如果路径没有足够的组件,这将产生损坏的结果,因此您可能需要首先检查这一点。
或者,在 Bash 中我们可以使用正则表达式匹配[[ .. ]]
并选取匹配的片段:
$ if [[ $path =~ (/[^/]+/[^/]+)/(.*) ]]; then
echo "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}"
fi
/aaa/bbb ccc/ddd/eee/fff.txt
[[ ... ]]
作为一个条件,因此很容易使用if
here来确保路径有足够的组件。
答案2
我个人喜欢cut
这个:
$ echo "/aaa/bbb/ccc/ddd/eee/fff.txt" | cut -d'/' -f4-
ccc/ddd/eee/fff.txt
您只需将-f
参数调整到您希望它在目录树中解析的深度即可。
这显示了如何使用以下命令删除前两个字段awk
:
$ echo "/aaa/bbb/ccc/ddd/eee/fff.txt" | awk -F'/' -v OFS='/' '{$1=$2=$3=""; print}' | sed 's#///##'
ccc/ddd/eee/fff.txt
答案3
鉴于前缀是静态的,您可以使用参数扩展将其删除:
df_test=/aaa/bbb/ccc/ddd/eee/fff/ggg/hhh/iii.txt
cd /aaa/bbb
operate=${df_test#/aaa/bbb}
echo Operating on "$operate"