有没有一条命令可以根据相对路径获取绝对路径?
例如,我想让$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
依我看,最好的解决方案是在此处发布的一个:https://dev59.com/_HVC5IYBdhLWcg3wdw65#3373298。
它确实需要使用Python才能工作,但它似乎涵盖了所有或大多数边缘情况,并且是非常可移植的解决方案。
python -c "import os,sys; print(os.path.realpath(sys.argv[1]))" path/to/file
python -c "import os,sys; print(os.path.abspath(sys.argv[1]))" path/to/file
如果使用find
命令,最简单的方法是直接提供要搜索的绝对路径,例如:
find /etc
find `pwd`/subdir_of_current_dir/ -type f
如果你在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
}
(纯BSK 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
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
删除的所有内容。我曾试图在Mac OS Catalina,Ubuntu 16和Centos 7之间找到一个方便地跨平台的解决方案,但最终我决定使用内置的Python实现,并且它对我的Bash脚本非常有效。
to_abs_path() {
python -c "import os; print os.path.abspath('$1')"
}
to_abs_path "/some_path/../secrets"
absPath=$(pushd ../SOME_RELATIVE_PATH_TO_Directory > /dev/null && pwd && popd > /dev/null)
echo $absPath
cd $relative_path ; pwd
which
、locate
、find
、完整路径等方法。
x=your_file_name
$ x="nvi"
$ file -h `which $x`
/usr/local/bin/nvi: symbolic link to ../Cellar/nvi/1.81.6_5/bin/nvi
$ Y=$(file -h `which $x` | sed "s/$x: symbolic link to //")
$ echo $Y
/usr/local/bin/../Cellar/nvi/1.81.6_5/bin/nvi
dirname
,我们只获取路径部分。切换到该路径并且文件名应该会自动清理。$ cd `dirname $Y` ; pwd
/usr/local/Cellar/nvi/1.81.6_5/bin
ls
会确保绝对路径是有效的。$ ( cd `dirname ${Y}` ; ls `pwd`/${x} )
/usr/local/Cellar/nvi/1.81.6_5/bin/nvi
/usr/local/bin/nvi
实际上是 /usr/local/Cellar/nvi/1.81.6_5/bin/nvi
一个简化的示例,可以快速“转换”路径:$ (cd /usr/local/bin/../Cellar/nvi/1.81.6_5/bin ; pwd)
/usr/local/Cellar/nvi/1.81.6_5/bin
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/file.html https://pubs.opengroup.org/onlinepubs/9699919799/utilities/dirname.html
使用 Python 3 的先前答案的更新
to_abs_path() {
python -c "import os; print (os.path.abspath('$1'))"
}
允许
to_abs_path "./../some_file.txt"
除了 find $PWD
或者(在 bash 中)find ~+
这两个命令稍微方便一些,其他都是他们所说的。