다음과 같은 파일 경로가 있다면 ...
/home/smith/Desktop/Test
/home/smith/Desktop/Test/
부모 디렉토리가되도록 문자열을 어떻게 변경합니까?
예 :
/home/smith/Desktop
/home/smith/Desktop/
다음과 같은 파일 경로가 있다면 ...
/home/smith/Desktop/Test
/home/smith/Desktop/Test/
부모 디렉토리가되도록 문자열을 어떻게 변경합니까?
예 :
/home/smith/Desktop
/home/smith/Desktop/
답변:
dir=/home/smith/Desktop/Test
parentdir="$(dirname "$dir")"
후행 슬래시가있는 경우에도 작동합니다.
parentdir=$(dirname `pwd`)
...하지만 " 여기에 보이는 "것이 깨졌습니다. 수정 사항은 다음과 같습니다.
> pwd
/home/me
> x='Om Namah Shivaya'
> mkdir "$x" && cd "$x"
/home/me/Om Namah Shivaya
> parentdir="$(dirname "$(pwd)")"
> echo $parentdir
/home/me
echo $(cd ../ && pwd)
부모 디렉토리를 찾으려는 디렉토리에서 작업 하는 동안 사용하십시오 . 이 체인은 또한 슬래시가없는 장점이 있습니다.
echo
여기에 필요하지 않습니다 .
분명히 도트 디렉토리 파일 이름을 추가하여 상위 디렉토리가 제공됩니다.
/home/smith/Desktop/Test/.. # unresolved path
그러나 해결 된 경로 (점-점 경로 구성 요소가없는 절대 경로)가 필요합니다.
/home/smith/Desktop # resolved path
를 사용하는 최상위 답변의 문제 dirname
는 점이있는 경로를 입력하면 작동하지 않는다는 것입니다.
$ dir=~/Library/../Desktop/../..
$ parentdir="$(dirname "$dir")"
$ echo $parentdir
/Users/username/Library/../Desktop/.. # not fully resolved
이것은 더 강력합니다 :
dir=/home/smith/Desktop/Test
parentdir=`eval "cd $dir;pwd;cd - > /dev/null"`
당신은 /home/smith/Desktop/Test/..
뿐만 아니라 다음과 같은 더 복잡한 경로를 공급할 수 있습니다
$ dir=~/Library/../Desktop/../..
$ parentdir=`eval "cd $dir;pwd;cd - > /dev/null"`
$ echo $parentdir
/Users # the fully resolved path!
편집 : 작동하지 않으면 cd
때로는 일반적인 관행과 같이 수정되지 않았는지 확인하십시오 .
$ which cd
cd is a function #cd was modified to print extra info, so use "builtin cd" to override
cd ()
{
builtin cd "$@";
ls -FGAhp
}
...
eval
사용자 입력을 구문 분석하여 시스템에 대해 나쁜 일을 예상하지 않거나 어딘가에 놓을 수있는 사용자 입력을 구문 분석 할 수있는 경우 사용 은 좋지 않습니다. pushd $dir 2>&1 >/dev/null && pwd && popd 2>&1 >/dev/null
대신에 사용할 수 있습니까 eval
?
eval
: 그냥하십시오 parentdir=$(cd -- "$dir" && pwd)
. cd
이 하위 쉘에서 실행 되므로 cd
이전 위치 로 돌아갈 필요가 없습니다 . 는 --
경우 여기의 확장이다 $dir
하이픈으로 시작됩니다. 은 &&
단지 방지하는 것입니다 parentdir
이 때 비어 있지 않은 내용을 가지고 cd
suceed하지 않았다.
나는 매우 짧고 명확하며 보장 된 코드를 좋아합니다. 외부 프로그램을 실행하지 않는 경우 보너스 포인트는 많은 수의 항목을 처리 해야하는 날이므로 눈에 띄게 빠릅니다.
무엇을 보장하고 원하는지 확실하지 않으므로 어쨌든 제공하십시오.
보증이 있으면 매우 짧은 코드로 할 수 있습니다. 아이디어는 bash 텍스트 대체 기능을 사용하여 마지막 슬래시와 그 다음에 오는 것을 잘라내는 것입니다.
원래 질문의 간단한 사례에서 더 복잡한 사례에 대한 답변.
P=/home/smith/Desktop/Test ; echo "${P%/*}"
/home/smith/Desktop
P=/home/smith/Desktop/Test/ ; echo "${P%/*/}/"
/home/smith/Desktop/
for P in \
/home/smith/Desktop/Test \
/home/smith/Desktop/Test/
do
P_ENDNOSLASH="${P%/}" ; echo "${P_ENDNOSLASH%/*}"
done
/home/smith/Desktop
/home/smith/Desktop
for P in \
/home/smith/Desktop/Test \
/home/smith/Desktop/Test/ \
/home/smith///Desktop////Test//
do
P_NODUPSLASH="${P//\/*(\/)/\/}"
P_ENDNOSLASH="${P_NODUPSLASH%%/}"
echo "${P_ENDNOSLASH%/*}";
done
/home/smith/Desktop
/home/smith/Desktop
/home/smith/Desktop
${BASH_SOURCE[0]}
이를 통해 공급되지 않은 경우 스크립트의 전체 경로가 될 것이다 source
또는 .
.
bash: dirname 'Test': syntax error: invalid arithmetic operator (error token is "'Test'")
합니다. 연결된 코드도 잘못되었습니다.
dirname Test
디렉토리에서 실행 해보십시오 Test
.
절대 경로가 필요한지 여부에 따라 추가 단계를 수행 할 수 있습니다.
child='/home/smith/Desktop/Test/'
parent=$(dirname "$child")
abs_parent=$(realpath "$parent")
이것을 사용하십시오 : export MYVAR="$(dirname "$(dirname "$(dirname "$(dirname $PWD)")")")"
네 번째 부모 디렉토리를 원한다면
export MYVAR="$(dirname "$(dirname "$(dirname $PWD)")")"
세 번째 부모 디렉토리를 원한다면
export MYVAR="$(dirname "$(dirname $PWD)")"
두 번째 부모 디렉토리를 원한다면
추악하지만 효율적인
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_: /
아이디어 / 댓글에서 시작 Charles Duffy-12 월 17 '14 일 오전 5:32 Bash 스크립트에서 현재 디렉토리 이름 가져 오기 (전체 경로 없음) 주제
#!/bin/bash
#INFO : /programming/1371261/get-current-directory-name-without-full-path-in-a-bash-script
# comment : by Charles Duffy - Dec 17 '14 at 5:32
# at the beginning :
declare -a dirName[]
function getDirNames(){
dirNr="$( IFS=/ read -r -a dirs <<<"${dirTree}"; printf '%s\n' "$((${#dirs[@]} - 1))" )"
for(( cnt=0 ; cnt < ${dirNr} ; cnt++))
do
dirName[$cnt]="$( IFS=/ read -r -a dirs <<<"$PWD"; printf '%s\n' "${dirs[${#dirs[@]} - $(( $cnt+1))]}" )"
#information – feedback
echo "$cnt : ${dirName[$cnt]}"
done
}
dirTree=$PWD;
getDirNames;
..
' 를 사용할 수는 있지만 아마도 마음에 들지 않은 것일 수도 있습니다.