我想分割这一行
/home/edwprod/abortive_visit/bin/abortive_proc_call.ksh
到
/home/edwprod/abortive_visit/bin
使用sed
或awk
脚本?你可以帮忙吗?
答案 0 :(得分:14)
目录名
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 :(得分: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/'
答案 2 :(得分:2)
awk + for:
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}'
答案 3 :(得分:1)
我猜这段带 awk 的代码与 dirname 完全相同。
它非常简单,工作成本非常低。祝你好运。
的代码强> 的
$ 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
- &gt; /app/java/jdk1.7.0_71/bin
foo=/app/java/jdk1.7.0_71/bin/
- &gt; /app/java/jdk1.7.0_71
foo=/app/java/jdk1.7.0_71/bin
- &gt; /app/java/jdk1.7.0_71
foo=/app/
- &gt; /
foo=/app
- &gt; /
foo=fighters/
- &gt; .
更多强> 的
如果您没有这样的awk分隔符,请尝试这种方式。
$ echo $foo | awk '{
dirname = gensub("/*[^/]*/*$", "", "", $0);
print (dirname == "" ? (substr($0, 1, 1) == "/" ? "/" : ".") : dirname);
}'
答案 4 :(得分:0)
对于现在可用的大多数平台和Unix / Linux shell dirname
:
dirname /home/edwprod/abortive_visit/bin/abortive_proc_call.ksh
使用dirname
是最简单的方法,但不建议用于跨平台脚本,例如在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/
这样的路径,它会打印.
即:
/
aa
和aa/
/
开头的路径和路径/
本身。$str
最后包含\n
,那么它是正确的,即使有很多\n
/
(//
///
)的所有组合更改为/
注意强>
basename
的替代方案可能很有用:
echo "$str" | awk -F"/" '{print $NF}' -
答案 5 :(得分:0)
此外,除了肯特的答案,另一种awk解决方案是:
awk 'BEGIN{FS=OFS="/"}{NF--}1'
与肯特(Kent)所患的疾病相同。以下较长的Awk纠正了所有缺陷:
awk 'BEGIN{FS=OFS="/"}{gsub("/+","/")}
{s=$0~/^\//;NF-=$NF?1:2;$0=$0?$0:(s?"/":".")};1' <file>
下表显示了区别:
| path | dirname | awk full | awk short |
|------------+---------+----------+-----------|
| . | . | . | |
| / | / | / | |
| foo | . | . | |
| foo/ | . | . | foo |
| foo/bar | foo | foo | foo |
| foo/bar/ | foo | foo | foo/bar |
| /foo | / | / | |
| /foo/ | / | / | /foo |
| /foo/bar | /foo | /foo | /foo |
| /foo/bar/ | /foo | /foo | /foo/bar |
| /foo///bar | /foo | /foo | /foo// |
注意: dirname
是真正的解决方法,除非您必须处理存储在文件中的大量文件。
答案 6 :(得分:0)
我总是惊讶于一些单线球员的聪明程度。就我而言,我追求可读性,所以这是我的实现。这是一个普通的 Bourne shell 脚本,依赖于模仿 dirname
的 sed 和 grep。
strip_trailing_slashes() {
printf "$1" | sed 's/[/]*$//'
}
# If empty arg, return .
# If nothing but slashes, return /
# If no slashes after stripping all trailing slashes, return .
# Otherwise, return everything up until last path component
dirname() {
if [ -z "$1" ]; then printf '.'; return; fi
if ! $(printf "$1" | grep -q '[^/]'); then printf '/'; return; fi
local s="$(strip_trailing_slashes $1)"
if ! $(printf "$s" | grep -q '/'); then printf '.'; fi
printf "$(strip_trailing_slashes $(printf $s | sed 's/[^/]*$//'))"
}
这是一个 gist,其中包括针对以下情况的 44 项测试 -- 还针对 dirname
进行了兼容性测试。
Expect '.' for ('""' '.' '.foo' './foo' 'foo' 'foo/' 'foo///' '..' '..foo' '..foo//' '../')
Expect '/' for ('/' '//' '///')
Expect 'a/b' for ('a/b/c' 'a/b/c/' 'a/b/c///')
Expect '/a/b' for ('/a/b/c' '/a/b/c/' '/a/b/c///')
Expect '//a/b' for ('//a/b/c' '//a/b/c//' '/a/b/c')
几点:
dirname
不同。 oneliner 版本将下面的“//a/b/c”转换成“/a/b”,这可能不是你想要的; dirname
不会去除额外的前导斜杠并返回“//a/b”。我选择使我的版本与 dirname
兼容。 (没有一个版本在中间分隔路径组件中去除额外的斜线)。向@Роман Коптев 致敬oneliner 版本!