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

时间:2013-07-29 10:22:43

标签: unix awk substr

我有一个简单的要求如下,
我用绝对目录获取文件名 例如/home/parent/child/filename
我的要求是从中删除文件名。
我试过的是:

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

完美无缺 但是这里的硬编码$5如果我的输入具有如下结构可能会有所不同:

/home/parent/child1/child2/filename

因此,如果没有硬编码,它应该是动态的。这是逻辑:
始终取最后一个将是文件名的字段(因此需要反向检查)。

任何人都可以帮我解决awk substr函数或任何其他函数吗?

8 个答案:

答案 0 :(得分:166)

使用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

答案 1 :(得分:28)

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

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

答案 2 :(得分:5)

另一种选择是使用bash parameter substitution

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

答案 3 :(得分:5)

如果你对Perl解决方案持开放态度,这里有一个类似于fedorqui的awk解决方案:

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

-F/指定/作为字段分隔符
$F[-1]@F autosplit数组

中的最后一个元素

答案 4 :(得分:3)

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

如果您不使用双引号,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

答案 5 :(得分: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

答案 6 :(得分:1)

像迟到5年一样,我知道,感谢所有建议,我以前是通过以下方式做到这一点的:

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

很高兴发现有更好的举止

答案 7 :(得分:-1)

您也可以使用:

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

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