bash相当于Python的os.path.normpath?

时间:2011-06-18 01:35:50

标签: python bash path find normalization

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

matt@stanley:~/src/libtelnet-0.20/test$ find
.
./Makefile
./Makefile.in
./Makefile.am
...

7 个答案:

答案 0 :(得分: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

如您所见,我对临时shell脚本有一个相当直观的命名标准: - )

答案 1 :(得分: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!^\./!!'

答案 2 :(得分:1)

我通常使用find的{​​{1}}参数来完成此操作。

如果您在多个路径中搜索,以下工作正常:

-printf

如果您在find path1 path2 搜索

,以下情况可以正常工作
.

如果您有混合路径(例如find -printf '%P\n' ),则必须使用find path1 path2 .

答案 3 :(得分:1)

怎么样:

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

我认为没有任何内置的bash函数来完成Python的normpath所做的一切。您可能最好完全描述 您想要执行的转换。

答案 4 :(得分: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"
}

答案 5 :(得分:0)

可能重复here。但是,如果你只是想要消除领先./你可以做到

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

答案 6 :(得分:0)

我找到了它:它被称为realpath! 输入类似的内容:

realpath ..   # the most interesting thing

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

并享受!