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

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

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

效果非常好。
然而,我硬编码 $5,这将是不正确的,如果我的输入有以下结构:

/home/parent/child1/child2/filename

因此,通用解决方案要求始终使用 最后字段(即文件名)。

有没有一种简单的方法来实现 awk subr 函数?

197800 次浏览

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

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

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

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

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

你亦可使用:

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

或者

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

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

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

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

这应该是一个评论的基本名称的答案,但我没有足够的观点。

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

我知道我迟了三年,但是..。 你应该考虑参数扩展,它是内置的,而且速度更快。

如果输入是 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

像5年后,我知道,感谢所有的建议,我过去常常这样做:

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

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

您可以跳过所有复杂的 regex:

 echo '/home/parent/child1/child2/filename' |


mawk '$!_=$-_=$NF' FS='[/]'
filename

倒数第二 :

 mawk '$!--NF=$NF' FS='/'
child2

倒数第三名:

 echo '/home/parent/child1/child2/filename' |


mawk '$!--NF=$--NF' FS='[/]'
 

child1

倒数第四名:

 mawk '$!--NF=$(--NF-!-FS)' FS='/'


echo '/home/parent/child000/child00/child0/child1/child2/filename' |
child0
echo '/home/parent/child1/child2/filename'
parent

主要警告 :

- `gawk/nawk` has a slight discrepancy with `mawk` regarding


- how it tracks multiple,
- and potentially conflicting, decrements to `NF`,


- so other than the 1st solution regarding last field,
- the rest for now, are only applicable to `mawk-1/2`

我刚刚意识到这样在 mawk/gawk/nawk中要干净得多:

echo '/home/parent/child1/child2/filename' | …

'

awk ++NF FS='.+/' OFS=      # updated such that
# root "/" still gets printed

'

filename