sed
我需要通过, (与 pf 的作用相反)从路径中删除第一个目录basename
。
例如
echo "/mnt/VPfig/Amer/AR4/Celtel/files/COM.txt" | sed ...
我应该得到:
/VPfig/Amer/AR4/Celtel/files/COM.txt
答案1
尝试:
echo "/mnt/VPfig/Amer/AR4/Celtel/files/COM.txt" | sed 's|^/[^/]*||'
这给了我:
/VPfig/Amer/AR4/Celtel/files/COM.txt
它查找第一个/
,后跟/
尽可能多的非 - ,然后用空字符串替换它们。
答案2
在 POSIX shell 中:
$ x='/mnt/VPfig/Amer/AR4/Celtel/files/COM.txt'
$ printf "/%s\n" "${x#/*/}"
/VPfig/Amer/AR4/Celtel/files/COM.txt
解释
这参数扩展 ${x#/*/}
删除路径的前导组件,用两个/
s 将其包围,然后将printf
前导重新钉上/
。
答案3
最简单的方法是/
从字符串开头删除最短的非字符字符串。
在大多数正则表达式语言中,[ ]
os 是一个与括号内的任何内容相匹配的字符类。[abc]
将匹配ora
或b
。是一个c
[^ ]
否定的字符类,匹配除其中字符之外的任何内容。因此,[^/]*
将匹配最长的非字符字符串/
。^
正则表达式开头的A使其仅在输入字符串的开头匹配。结合这些,您可以执行以下操作:
$ echo "/mnt/VPfig/Amer/AR4/Celtel/files/COM.txt" | sed 's/^\/[^/]*//'
/VPfig/Amer/AR4/Celtel/files/COM.txt
或者,您可以将 awk 的输入字段分隔符设置为/
并打印除最后一个字段之外的所有内容:
$ echo "/mnt/VPfig/Amer/AR4/Celtel/files/COM.txt" |
awk -F/ '{for(i=3;i<=NF;i++){printf "/%s",$i};print ""}'
或者你可以使用一些 Perl 技巧:
$ echo "/mnt/VPfig/Amer/AR4/Celtel/files/COM.txt" |
perl -F/ -lane 'print "/",join "/",@F[2..$#F]'
/VPfig/Amer/AR4/Celtel/files/COM.txt
或者,一些更好的 Perl 技巧正如@Joseph R. 所建议的。:
$ echo "/mnt/VPfig/Amer/AR4/Celtel/files/COM.txt" | perl -pe
perl -pe 's{^/.*?(?=/)}{}'
或者甚至简单地:
$ echo "/mnt/VPfig/Amer/AR4/Celtel/files/COM.txt" | perl -pe 's#/[^/]+/#/#'
/VPfig/Amer/AR4/Celtel/files/COM.txt
最后,您还可以使用 Perl 正则表达式的强大功能grep
:
$ echo "/mnt/VPfig/Amer/AR4/Celtel/files/COM.txt" | grep -oP '/[^/]+?\K/.*'
/VPfig/Amer/AR4/Celtel/files/COM.txt