130

我正在尝试使用awk给定文件的绝对路径来获取文件的名称。
例如,当给定/home/parent/child/filename我想要的输入路径时,filename 我尝试过:

awk -F "/" '{print $5}' input

效果很好。
但是,我是硬编码$5,如果我的输入具有以下结构,这将是不正确的:

/home/parent/child1/child2/filename

因此,通用解决方案需要始终采用最后一个字段(将是文件名)。

有没有一种简单的方法可以使用 awk substr 函数来做到这一点?

4

8 回答 8

266

awk使用您可以定义的基于字段分隔符拆分字段中的行的事实。因此,为您定义字段分隔符/可以说:

awk -F "/" '{print $NF}' input

NF指当前记录的字段数,print$NF表示打印最后一个。

所以给定一个这样的文件:

/home/parent/child1/child2/child3/filename
/home/parent/child1/child2/filename
/home/parent/child1/filename

这将是输出:

$ awk -F"/" '{print $NF}' file
filename
filename
filename
于 2013-07-29T10:25:08.813 回答
36

在这种情况下,最好使用basename而不是awk

 $ basename /home/parent/child1/child2/filename
 filename
于 2013-07-29T10:25:53.380 回答
7

如果您愿意接受 Perl 解决方案,这里有一个类似于 fedorqui 的 awk 解决方案:

perl -F/ -lane 'print $F[-1]' input

-F/指定/字段分隔符是自动拆分数组
$F[-1]中的最后一个元素@F

于 2015-09-10T20:24:55.467 回答
5

另一种选择是使用bash 参数替换

$ foo="/home/parent/child/filename"
$ echo ${foo##*/}
filename
$ foo="/home/parent/child/child2/filename"
$ echo ${foo##*/}
filename
于 2013-07-29T12:04:58.800 回答
3

我知道我在这方面迟到了 3 年,但是......你应该考虑参数扩展,它是内置的并且速度更快。

如果你的输入在一个 var 中,比如说 $var1,就做${var1##*/}. 往下看

$ var1='/home/parent/child1/filename'
$ echo ${var1##*/}
filename
$ var1='/home/parent/child1/child2/filename'
$ echo ${var1##*/}
filename
$ var1='/home/parent/child1/child2/child3/filename'
$ echo ${var1##*/}
filename
于 2017-05-10T03:38:21.500 回答
3

它应该是对基本名称答案的评论,但我没有足够的意义。

如果不使用双引号,basename则不适用于有空格字符的路径:

$ basename /home/foo/bar foo/bar.png
bar

好用引号“”

$ basename "/home/foo/bar foo/bar.png"
bar.png

文件示例

$ cat a
/home/parent/child 1/child 2/child 3/filename1
/home/parent/child 1/child2/filename2
/home/parent/child1/filename3

$ while read b ; do basename "$b" ; done < a
filename1
filename2
filename3
于 2016-07-22T08:50:22.207 回答
2

就像晚了 5 年,我知道,感谢所有的建议,我曾经这样做过以下方式:

$ echo /home/parent/child1/child2/filename | rev | cut -d '/' -f1 | rev
filename

很高兴注意到有更好的礼仪

于 2018-08-24T16:03:40.067 回答
-1

You can also use:

    sed -n 's/.*\/\([^\/]\{1,\}\)$/\1/p'

or

    sed -n 's/.*\/\([^\/]*\)$/\1/p'
于 2013-07-30T02:11:23.097 回答