使用awk substr获取最后一个字段


101

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

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

完美地运作。
但是,我很难编码$5,如果我的输入具有以下结构,那将是不正确的:

/home/parent/child1/child2/filename

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

使用awk substr函数有一种简单的方法吗?


2
正如有人指出,使用basename是这样做的官方方法,因此,awk轻描淡写是不好的。:D
Kashyap

Answers:


209

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

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

如是NF指当前记录的字段数,打印$NF是指打印最后一个字段。

因此,给定这样的文件:

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

这将是输出:

$ awk -F"/" '{print $NF}' file
filename
filename
filename

3
完美运作。我没想到$ NF变量。感谢您的直接而有效的答复。
2013年

6
对于倒数第二个,使用$(NF-1)
Itachi

1
正在编写脚本以与某些docker命令配合使用,这确实达到了目的。谢谢!
哈林

31

在这种情况下,最好使用basename代替awk

 $ basename /home/parent/child1/child2/filename
 filename

4
@Mari FYI dirname进行相反的操作,剥离文件而不是路径。
克里斯·西摩

5

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

$ foo="/home/parent/child/filename"
$ echo ${foo##*/}
filename
$ foo="/home/parent/child/child2/filename"
$ echo ${foo##*/}
filename

5

如果您愿意使用Perl解决方案,那么这里有一种类似于fedorqui的awk解决方案的方法:

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

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


1
谢谢。这帮助我获得了最后一个领域。perl -F“ /” -lane'print $ F [-2]'输入
riderchap 2015年

从管道输入接收时,这对我有用。完全忘记了perl。
克里斯托弗

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

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

2

就像迟到了5年,我知道,感谢所有提案,我以前是通过以下方式做到这一点的:

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

很高兴注意到有更好的举止


-1

您还可以使用:

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

要么

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

1
在这一点上,没有人支持这个答案,可能是因为它相当丑陋:)
Josip Rodin
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.