Dividir um caminho / caminho / para /

0

Eu tenho um caminho explícito para um arquivo:

/aaa/bbb/ccc/ddd/eee/fff.txt

Eu preciso de cd /aaa/bbb e executar uma operação em ccc/ddd/eee/fff.txt .

Eu tenho o primeiro bit descoberto:

df_test=/aaa/bbb/ccc/ddd/eee/fff.txt
cd $( echo ${df_test} | awk -F/ '{print "/"$2"/"$3}' )

Como faço para cortar os dois primeiros passos no caminho e operar no restante? Além disso, não vou saber com antecedência a profundidade desses arquivos. Eu posso ter

/aaa/bbb/ccc/ddd.txt
/aaa/bbb/ccc/ddd/eee/fff.txt
/aaa/bbb/ccc/ddd/eee/fff/ggg/hhh/iii.txt

Só preciso alterar os diretórios para / aaa / bbb e operar no caminho relativo restante.

    
por dafydd 05.07.2018 / 20:37

3 respostas

4

Em um shell padrão:

$ path=/aaa/bbb/ccc/ddd/eee/fff.txt
$ tail="${path#/*/*/}"
$ head="${path%/$tail}"
$ echo "$head" "$tail"
/aaa/bbb ccc/ddd/eee/fff.txt

"${path#/*/*/}" é o valor de path , mas a parte principal (mais curta) corresponde a /*/*/ removed, ou seja, a parte final. Então "${path%/$tail}" é path com uma barra e a parte da cauda removida.

Isso produzirá resultados quebrados se o caminho não tiver componentes suficientes, então você pode querer verificar isso primeiro.

Como alternativa, no Bash, podemos usar uma correspondência de expressão regular em [[ .. ]] e selecionar peças correspondentes:

$ if [[ $path =~ (/[^/]+/[^/]+)/(.*) ]]; then 
    echo "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}"
fi 
/aaa/bbb ccc/ddd/eee/fff.txt

[[ ... ]] funciona como uma condição, por isso é simples usar um if aqui para garantir que o caminho tenha componentes suficientes.

    
por 05.07.2018 / 20:50
0

Dado que o prefixo é estático, você pode usar a expansão de parâmetro para retirá-lo:

df_test=/aaa/bbb/ccc/ddd/eee/fff/ggg/hhh/iii.txt
cd /aaa/bbb
operate=${df_test#/aaa/bbb}
echo Operating on "$operate"
    
por 05.07.2018 / 20:53
0

Pessoalmente, eu gosto de cut para isso:

$ echo "/aaa/bbb/ccc/ddd/eee/fff.txt" | cut -d'/' -f4-
ccc/ddd/eee/fff.txt

Você simplesmente precisa ajustar o argumento -f com a profundidade que deseja analisar na árvore de diretórios.

Isso mostra como se livrar dos primeiros dois campos usando awk :

$ echo "/aaa/bbb/ccc/ddd/eee/fff.txt" | awk -F'/' -v OFS='/' '{$1=$2=$3=""; print}' | sed 's#///##'
ccc/ddd/eee/fff.txt
    
por 05.07.2018 / 20:53