programas - if en bash
Obtener el padre de un directorio en Bash (8)
Si tengo una ruta de archivo como ...
/home/smith/Desktop/Test
/home/smith/Desktop/Test/
¿Cómo cambio la cadena para que sea el directorio principal?
p.ej
/home/smith/Desktop
/home/smith/Desktop/
... pero lo que se "ve here " está roto. Aquí está la solución:
> pwd
/home/me
> x=''Om Namah Shivaya''
> mkdir "$x" && cd "$x"
/home/me/Om Namah Shivaya
> parentdir="$(dirname "$(pwd)")"
> echo $parentdir
/home/me
Claramente, el directorio padre se da simplemente añadiendo el nombre de un punto-punto:
/home/smith/Desktop/Test/.. # unresolved path
Pero debe querer la ruta resuelta (una ruta absoluta sin ningún componente de ruta de puntos y puntos):
/home/smith/Desktop # resolved path
El problema con las respuestas principales que usan dirname
es que no funcionan cuando ingresa una ruta con puntos-puntos:
$ dir=~/Library/../Desktop/../..
$ parentdir="$(dirname "$dir")"
$ echo $parentdir
/Users/username/Library/../Desktop/.. # not fully resolved
Esto es más poderoso :
dir=/home/smith/Desktop/Test
parentdir=`eval "cd $dir;pwd;cd - > /dev/null"`
Puedes alimentarlo /home/smith/Desktop/Test/..
, pero también caminos más complejos como:
$ dir=~/Library/../Desktop/../..
$ parentdir=`eval "cd $dir;pwd;cd - > /dev/null"`
$ echo $parentdir
/Users # the fully resolved path!
Dependiendo de si necesita caminos absolutos, es posible que desee dar un paso adicional:
child=''/home/smith/Desktop/Test/''
parent=$(dirname "$child")
abs_parent=$(realpath "$parent")
Simplemente use echo $(cd ../ && pwd)
mientras trabaja en el directorio cuyo directorio padre desea averiguar. Esta cadena también tiene la ventaja adicional de no tener barras inclinadas.
feo pero eficiente
function Parentdir()
{
local lookFor_ parent_ switch_ i_
lookFor_="$1"
#if it is not a file, we need the grand parent
[ -f "$lookFor_" ] || switch_="/.."
#length of search string
i_="${#lookFor_}"
#remove string one by one until it make sens for the system
while [ "$i_" -ge 0 ] && [ ! -d "${lookFor_:0:$i_}" ];
do
let i_--
done
#get real path
parent_="$(realpath "${lookFor_:0:$i_}$switch_")"
#done
echo "
lookFor_: $1
{lookFor_:0:$i_}: ${lookFor_:0:$i_}
realpath {lookFor_:0:$i_}: $(realpath ${lookFor_:0:$i_})
parent_: $parent_
"
}
lookFor_: /home/Om Namah Shivaya
{lookFor_:0:6}: /home/
realpath {lookFor_:0:6}: /home
parent_: /home
lookFor_: /var/log
{lookFor_:0:8}: /var/log
realpath {lookFor_:0:8}: /UNIONFS/var/log
parent_: /UNIONFS/var
lookFor_: /var/log/
{lookFor_:0:9}: /var/log/
realpath {lookFor_:0:9}: /UNIONFS/var/log
parent_: /UNIONFS/var
lookFor_: /tmp//res.log/..
{lookFor_:0:6}: /tmp//
realpath {lookFor_:0:6}: /tmp
parent_: /
lookFor_: /media/sdc8/../sdc8/Debian_Master//a
{lookFor_:0:35}: /media/sdc8/../sdc8/Debian_Master//
realpath {lookFor_:0:35}: /media/sdc8/Debian_Master
parent_: /media/sdc8
lookFor_: /media/sdc8//Debian_Master/../Debian_Master/a
{lookFor_:0:44}: /media/sdc8//Debian_Master/../Debian_Master/
realpath {lookFor_:0:44}: /media/sdc8/Debian_Master
parent_: /media/sdc8
lookFor_: /media/sdc8/Debian_Master/../Debian_Master/For_Debian
{lookFor_:0:53}: /media/sdc8/Debian_Master/../Debian_Master/For_Debian
realpath {lookFor_:0:53}: /media/sdc8/Debian_Master/For_Debian
parent_: /media/sdc8/Debian_Master
lookFor_: /tmp/../res.log
{lookFor_:0:8}: /tmp/../
realpath {lookFor_:0:8}: /
parent_: /
usa esto: export MYVAR="$(dirname "$(dirname "$(dirname "$(dirname $PWD)")")")"
si quieres el directorio 4th parent
export MYVAR="$(dirname "$(dirname "$(dirname $PWD)")")"
si quieres el tercer directorio padre
export MYVAR="$(dirname "$(dirname $PWD)")"
si quieres el segundo directorio principal
dir=/home/smith/Desktop/Test
parentdir="$(dirname "$dir")"
Funciona si hay una barra final, también.