是否有一个命令来检索给定相对路径的绝对路径?
例如,我想要$line包含dir ./etc/中每个文件的绝对路径
find ./ -type f | while read line; do
echo $line
done
是否有一个命令来检索给定相对路径的绝对路径?
例如,我想要$line包含dir ./etc/中每个文件的绝对路径
find ./ -type f | while read line; do
echo $line
done
当前回答
#! /bin/sh
echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"
一些解释
这个脚本获取相对路径作为参数"$1" 然后我们得到该路径的dirname部分(你可以将dir或file传递给这个脚本): 然后我们将“$(dirname“$1”)cd到这个相对目录中,并通过运行pwd shell命令获得它的绝对路径 在此之后,我们将basename附加到绝对路径: 作为最后一步,我们重复它
其他回答
我认为这是最便携的:
abspath() {
cd "$(dirname "$1")"
printf "%s/%s\n" "$(pwd)" "$(basename "$1")"
cd "$OLDPWD"
}
但是,如果路径不存在,它将失败。
类似于@ernest-a的答案,但不影响$OLDPWD或定义一个新函数,您可以触发一个子shell (cd <path>;pwd)
$ pwd
/etc/apache2
$ cd ../cups
$ cd -
/etc/apache2
$ (cd ~/..; pwd)
/Users
$ cd -
/etc/cups
如果你在Mac OS X上使用bash,它既没有realpath也没有readlink可以打印绝对路径,你可以选择编写自己的版本来打印它。 这是我的实现:
(纯bash)
abspath(){
local thePath
if [[ ! "$1" =~ ^/ ]];then
thePath="$PWD/$1"
else
thePath="$1"
fi
echo "$thePath"|(
IFS=/
read -a parr
declare -a outp
for i in "${parr[@]}";do
case "$i" in
''|.) continue ;;
..)
len=${#outp[@]}
if ((len==0));then
continue
else
unset outp[$((len-1))]
fi
;;
*)
len=${#outp[@]}
outp[$len]="$i"
;;
esac
done
echo /"${outp[*]}"
)
}
(用呆呆的)
abspath_gawk() {
if [[ -n "$1" ]];then
echo $1|gawk '{
if(substr($0,1,1) != "/"){
path = ENVIRON["PWD"]"/"$0
} else path = $0
split(path, a, "/")
n = asorti(a, b,"@ind_num_asc")
for(i in a){
if(a[i]=="" || a[i]=="."){
delete a[i]
}
}
n = asorti(a, b, "@ind_num_asc")
m = 0
while(m!=n){
m = n
for(i=1;i<=n;i++){
if(a[b[i]]==".."){
if(b[i-1] in a){
delete a[b[i-1]]
delete a[b[i]]
n = asorti(a, b, "@ind_num_asc")
break
} else exit 1
}
}
}
n = asorti(a, b, "@ind_num_asc")
if(n==0){
printf "/"
} else {
for(i=1;i<=n;i++){
printf "/"a[b[i]]
}
}
}'
fi
}
(纯BSD AWK)
#!/usr/bin/env awk -f
function abspath(path, i,j,n,a,b,back,out){
if(substr(path,1,1) != "/"){
path = ENVIRON["PWD"]"/"path
}
split(path, a, "/")
n = length(a)
for(i=1;i<=n;i++){
if(a[i]==""||a[i]=="."){
continue
}
a[++j]=a[i]
}
for(i=j+1;i<=n;i++){
delete a[i]
}
j=0
for(i=length(a);i>=1;i--){
if(back==0){
if(a[i]==".."){
back++
continue
} else {
b[++j]=a[i]
}
} else {
if(a[i]==".."){
back++
continue
} else {
back--
continue
}
}
}
if(length(b)==0){
return "/"
} else {
for(i=length(b);i>=1;i--){
out=out"/"b[i]
}
return out
}
}
BEGIN{
if(ARGC>1){
for(k=1;k<ARGC;k++){
print abspath(ARGV[k])
}
exit
}
}
{
print abspath($0)
}
例子:
$ abspath I/am/.//..//the/./god/../of///.././war
/Users/leon/I/the/war
use:
find "$(pwd)"/ -type f
获取所有文件或
echo "$(pwd)/$line"
显示完整路径(如果相对路径关系到)
我发现Eugen Konkov的答案是最好的,因为它不需要安装任何程序。但是,对于不存在的目录,它将失败。
我写了一个函数,适用于不存在的目录:
function getRealPath()
{
local -i traversals=0
currentDir="$1"
basename=''
while :; do
[[ "$currentDir" == '.' ]] && { echo "$1"; return 1; }
[[ $traversals -eq 0 ]] && pwd=$(cd "$currentDir" 2>&1 && pwd) && { echo "$pwd/$basename"; return 0; }
currentBasename="$(basename "$currentDir")"
currentDir="$(dirname "$currentDir")"
[[ "$currentBasename" == '..' ]] && (( ++traversals )) || { [[ traversals -gt 0 ]] && (( traversals-- )) || basename="$currentBasename/$basename"; }
done
}
它通过使用dirname向上遍历直到cd成功,然后返回当前目录加上dirname删除的所有内容来解决不存在目录的问题。