2011-12-19 85 views
5

我想這條線使用絕對路徑提取目錄名awk或者sed

/home/edwprod/abortive_visit/bin/abortive_proc_call.ksh 

拆分使用sedawk腳本

/home/edwprod/abortive_visit/bin 

?你能幫忙嗎?

+0

什麼是上下文?這是在一個文件?你有多次發生?你做... ? – fge 2011-12-19 10:58:57

+1

sed和awk對此過度殺傷,shell直接爲此提供了實用程序。 – Mat 2011-12-19 11:01:51

+1

如果你使用bash:爲什麼不使用'dirname'命令? – codeling 2011-12-19 11:02:04

回答

5

可能是命令dirname是你在尋找什麼?

dirname /home/edwprod/abortive_visit/bin/abortive_proc_call.ksh 

或者,如果你想SED,所以看到我的解決方案:

echo /home/edwprod/abortive_visit/bin/abortive_proc_call.ksh | sed 's/\(.*\)\/.*/\1/' 
+1

「基於sed」的解決方案存在僅包含基本名稱的路徑問題。在這種情況下'dirname'返回'.'。 – 2016-04-18 10:20:33

11

目錄名

kent$ dirname "/home/edwprod/abortive_visit/bin/abortive_proc_call.ksh" 
/home/edwprod/abortive_visit/bin 

sed的

kent$ echo "/home/edwprod/abortive_visit/bin/abortive_proc_call.ksh"|sed 's#/[^/]*$##' 
/home/edwprod/abortive_visit/bin 

的grep

kent$ echo "/home/edwprod/abortive_visit/bin/abortive_proc_call.ksh"|grep -oP '^/.*(?=/)' 
/home/edwprod/abortive_visit/bin 

AWK

kent$ echo "/home/edwprod/abortive_visit/bin/abortive_proc_call.ksh"|awk -F'/[^/]*$' '{print $1}' 
/home/edwprod/abortive_visit/bin 
+1

在「dirname」的所有這些替代方法中,僅包含基本名稱的路徑存在問題。 'dirname'在這種情況下給出'.'。 'grep'版本返回一個空字符串,其他的則作爲'basename' – 2016-04-18 10:18:50

1

AWK +爲:

echo "/home/edwprod/abortive_visit/bin/abortive_proc_call.ksh" | awk 'BEGIN{res=""; FS="/";}{ for(i=2;i<=NF-1;i++) res=(res"/"$i);} END{print res}' 
0

對於大多數平臺和Unix/Linux外殼現已dirname

dirname /home/edwprod/abortive_visit/bin/abortive_proc_call.ksh 

使用的dirname是simpliest方式,但不推薦用於例如最後的跨平臺腳​​本版本autoconf文檔http://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Limitations-of-Usual-Tools.html#Limitations-of-Usual-Tools

所以sed基替代的dirname我的全功能版本:

str="/home/edwprod/abortive_visit/bin/abortive_proc_call.ksh" 
echo "$str" | sed -n -e '1p' | sed -e 's#//*#/#g' -e 's#\(.\)/$#\1#' -e 's#^[^/]*$#.#' -e 's#\(.\)/[^/]*$#\1#' - 

例子:

它的工作原理就像dirname

  • 對於像/aa/bb/cc路徑,它將打印/aa/bb
  • 對於像/aa/bb這樣的路徑,它將打印/aa
  • 對於像/aa/bb/這樣的路徑,它也會打印/aa
  • 對於像/aa/路徑,它將打印/aa
  • 對於像/路徑,它將打印/
  • 對於像aa路徑,它將打印.
  • 對於像aa/路徑,它將打印.

即:

  • 它與尾隨/
  • 它的工作原理與正確包含像aaaa/
  • 它與開始/路徑和路徑/本身只有正確基本名稱的路徑是正確的。
  • 它適用於任何$str正確的,如果它包含\n在年底或沒有,甚至有許多\n
  • 它採用跨平臺的sed命令
  • 它改變了//////)的所有組合/
  • 它無法正確處理當前語言環境中包含換行符和字符無效的路徑。

注意 替代計劃basename可能是有用的:

echo "$str" | awk -F"/" '{print $NF}' - 
0

此代碼與AWK將工作完全是一樣目錄名,我猜。

它非常簡單,工作成本非常低。祝你好運。

代碼

$ foo=/app/java/jdk1.7.0_71/bin/java 
$ echo "$foo" | awk -F "/?[^/]*/?$" ' 
{ print ($1 == "" ? (substr($0, 1, 1) == "/" ? "/" : ".") : $1); }' 

結果

/app/java/jdk1.7.0_71/bin

測試

  • foo=/app/java/jdk1.7.0_71/bin/java - >/app/java/jdk1.7.0_71/bin
  • foo=/app/java/jdk1.7.0_71/bin/ - >/app/java/jdk1.7.0_71
  • foo=/app/java/jdk1.7.0_71/bin - >/app/java/jdk1.7.0_71
  • foo=/app/ - >/
  • foo=/app - >/
  • foo=fighters/ - >.

如果你不提供此類AWK分隔符,嘗試這種方式。

$ echo $foo | awk '{ 
dirname = gensub("/?[^/]*/?$", "", "", $0); 
print (dirname == "" ? (substr($0, 1, 1) == "/" ? "/" : ".") : dirname); 
}'