2014-02-24 37 views
0

我有一個腳本,它執行大量的文件處理,並且它足夠接收使用空字符作爲安全分隔符的路徑。但是,它將所有路徑處理爲絕對路徑(節省一些頭痛),但是對於輸出目的來說這些路徑有點不便,所以我想從輸出中刪除一部分路徑。現在,有很多選項值得思考,但難點在於以一種對我可能遇到的任意路徑安全的方式使用這些選項,這就是事情變得棘手的地方。修剪文件路徑的最簡單,安全的方法

這裏有一個簡單的例子:

#!/bin/sh 
TARGET="$1" 
find "$TARGET" -print0 | while IFS= read -rd '' path; do 
    # Process path for output here 
    path_str="$path" 
    echo "$path_str" 
done 

所以在上面的腳本我想借此path並拆除TARGET,在可能的最兼容的方式(例如 - 具體什麼bash)的,它需要能夠從字符串的開頭僅刪除,即 - /foo/bar變爲bar/foo/bar/foo變成bar/foo/bar/foo仍然是/bar/foo。它還應該處理文件名中的任何可能的字符,包括某些文件系統支持的字符,例如tildes,冒號等,以及討厭的反引號字符。

我使用sed首先轉義了任何可能會破壞我的正則表達式的字符,但是這是一個非常混亂的做法,所以我希望有一些更簡單的方法。如果沒有的話,這裏的解決方案是迄今:

SAFE_CHARS='s:\([[/.*]\):\\\1:g' 
target_safe=$(printf '%s' "$TARGET" | sed "$SAFE_CHARS") 
path_str=$(printf '%s' "$path" | sed "s/^$target_safe//g') 

有可能是幾個字符缺失,我應該除了那些那些被逃脫,和任何錯別字道歉。

+0

'read'的'-d'選項是'bash'特定的(或者至少不是POSIX標準的一部分)。如果你使用它,你也可以使用其他'bash'擴展。 – chepner

回答

0

你可以試試這個簡單的查找:

export TARGET="$1" 
find "$TARGET" -exec bash -c 'sed "s|^$TARGET\/||" <<< "$1"' - '{}' \; 
+0

感謝您的建議,但我實際上更喜歡在工作時將'$ path'保留爲絕對路徑,我只是爲了輸出目的而修剪'$ TARGET',我會相應地澄清我的示例。另外,我不確定管道字符是否也適用於'sed',因爲例如HFS會高興地允許在文件名中使用管道字符。 – Haravikk

1

從字符串中刪除前綴,

$ TARGET=/foo/ 
$ path=/foo/bar 
$ echo "${path#$TARGET}" 
bar 

#運營商參數擴展是POSIX標準的一部分,將在任何工作符合POSIX標準的外殼。

+0

這似乎是最好的方法,但不幸的是我認爲我的shell環境(在OS X上)使用'ash'。它支持一些bash-isms,但是當我使用此方法修剪路徑時不會引發錯誤,但它也不起作用(只是返回完整的,未修改的路徑)。任何想法,爲什麼這可能是?我以爲它會拋出某種錯誤。 – Haravikk

+0

對不起,剛剛檢查過OS X確實使用'bash'作爲shell腳本,但由於某種原因,各種bash特有的功能不被支持,在終端中使用時工作得很好。我想我可以通過'bash'而不是'sh'來運行我的腳本,這是非常奇怪的工作環境! – Haravikk

+0

當'bash'被調用爲'sh'時,某些'bash'特有的特性被抑制,但這不應該是這種情況。正如我在我的回答中指出的那樣,'#'不是'bash'ism。你可以添加一個不適用的'TARGET' /'path'對的特定示例嗎? – chepner