2011-06-18 77 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