2011-06-18 82 views
5

os.path.normpath相当的bash是什么?具体来说,我有兴趣删除执行find时给出的前导./bash相当于Python的os.path.normpath?

[email protected]:~/src/libtelnet-0.20/test$ find 
. 
./Makefile 
./Makefile.in 
./Makefile.am 
...
+4

出于好奇,为什么? '。/ foo'可以正常工作,所以程序不应该在意... – Nemo

+0

'./ Makefile'不是绝对路径名,所以你可以毫无问题地使用它。那里。问题解决了。 – tzot

+0

@Nemo:标准化路径用在清单文件中。否则它根本就不是问题。 –

回答

2

好了,对于这一点,你可以简单地通过管道将sed输出,你没有正常化的完整路径:

your_command_goes_here | sed 's?^\./??' 

,将在开始摆脱所有./序列一条线。

下面的记录表明这个动作:

pax$ find -name 'qq*sh' 
./qq.ksh 
./qq.sh 
./qq.zsh 
./qq2.sh 
./qq2.zsh 
./qqq/qq.sh 

pax$ find -name 'qq*sh' | sed 's?^./??' 
qq.ksh 
qq.sh 
qq.zsh 
qq2.sh 
qq2.zsh 
qqq/qq.sh 

正如你所看到的,我有:-)

0

可能对于我的临时shell脚本一个相当直观的命名标准复制here。但如果你是在分段关闭领先只是感兴趣./你可以只是做

find -type f | sed 's/^\.\///' 
+0

我认为这实际上是错误的。你必须逃避'.'。 –

+0

@马特,好笑,我逃过了。但选择了一些格式>,但没有正确显示。我现在选择格式化前,它显示 –

1

我通常使用find-printf参数做到这一点。

,如果你在多条路径搜索以下工作正常:

find -printf '%P\n' 

如果你有一个混合路径(:

find path1 path2 

下,如果你在搜索.工作正常例如find path1 path2 .),则必须使用sed

+0

我不确定你的意思是混合路径它似乎工作找不到它。 –

2

我在努力寻找一个我想要使用os.path.normpath的案例。在具有符号链接,如UNIX或Windows,它返回的可能不是指定同一文件中的值系统:

$ mkdir /tmp/one /tmp/one/two 
$ ln -s /tmp/one/two /tmp/foo 
$ python -c 'import os.path; print os.path.normpath("/tmp/foo/..")' 
/tmp 
$ ls /tmp/foo/.. 
two 

/tmp/foo/../tmp/one,不/tmp

在Linux上,readlink -- "$filename"规范化路径中的所有符号链接。它返回的文件名称在执行命令时指定与$filename相同的文件(如果其中一个符号链接发生更改,它可能不会在稍后执行)。但大多数情况下,这不是必须的:只需保留$filename就可以了。

如果你想删除一个./前缀出于美观的原因,只是专门剥离它。

filename=${filename#./} 
find | sed -e 's!^\./!!' 
+0

规范化路径用在清单文件中。他们不可能是绝对的。 –

1

如何:

newpath=`echo -n "$oldpath" | python -c 'import sys, os; print os.path.normpath(sys.stdin.readline())'` 

我不认为有任何内置的bash函数来执行Python的normpath所做的一切。你可能会更好地描述究竟是你想要执行的转换。

+0

2和3之间的可惜打印开关行为:) –

1

写这样的事情:

normpath() { 
    [[ -z "$1" ]] && return 

    local skip=0 p o c 

    p="$1" 
    # check if we have absolute path and if not make it absolute 
    [[ "${p:0:1}" != "/" ]] && p="$PWD/$p" 

    o="" 
    # loop on processing all path elements 
    while [[ "$p" != "/" ]]; do 
     # retrive current path element 
     c="$(basename "$p")" 
     # shink our path on one(current) element 
     p="$(dirname "$p")" 

     # basename/dirname correct handle multimple "/" chars 
     # so we can not warry about them 

     # skip elements "/./" 
     [[ "$c" == "." ]] && continue 
     if [[ "$c" == ".." ]]; then 
      # if we have point on parent dir, we must skip next element 
      # in other words "a/abc/../c" must become "a/c" 
      let "skip += 1" 
     elif [[ 0 -lt $skip ]]; then 
      # skip current element and decrease skip counter 
      let "skip -= 1" 
     else 
      # this is normal element and we must add it to result 
      [[ -n "$o" ]] && o="/$o" 
      o="$c$o" 
     fi 
    done 

    # last thing - restore original absolute path sign 
    echo "/$o" 
} 
+0

你能为你的代码添加一些解释吗? – Ren

+1

我已添加一些评论。 为了不使绝对路径“清洁”,我们应该改变循环条件,并添加句柄,当路径超出它的起点时(增加所需数量“../”元素) –

0

我发现它:这就是所谓的realpath! 类型是这样的:

realpath .. # the most interesting thing 

realpath . # equivalent to `pwd' and to `echo $PWD' 

和享受!

+0

本来不错,但它不是标准的。 – GreenAsJade