次のようなファイルパスがある場合...
/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
成功しなかったときに空でないコンテンツが表示されないようにするためのものです。
私は非常に短く、明確で、保証されたコードが好きです。外部プログラムを実行しない場合のボーナスポイントは、膨大な数のエントリを処理する必要がある日であるため、著しく高速になります。
どんな保証があるのかわからないので、とにかく提供します。
保証がある場合は、非常に短いコードで実行できます。アイデアは、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
である。
これを使って : export MYVAR="$(dirname "$(dirname "$(dirname "$(dirname $PWD)")")")"
4番目の親ディレクトリが必要な場合
export MYVAR="$(dirname "$(dirname "$(dirname $PWD)")")"
3番目の親ディレクトリが必要な場合
export MYVAR="$(dirname "$(dirname $PWD)")"
2番目の親ディレクトリが必要な場合
醜いが効率的
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- Bashスクリプトでトピックの現在のディレクトリ名(フルパスなし)を取得するトピックについて14年12月17日5:32
#!/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;
..
'を使うことができますが、多分それはあなたが考えていたものとは全く違うかもしれません。