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

问题描述 投票:0回答:10

我正在尝试使用

awk
来获取给定文件绝对路径的文件名。
例如,当给定输入路径
/home/parent/child/filename
我想得到
filename
我试过了:

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

效果完美。
但是,我正在硬编码

$5
,如果我的输入具有以下结构,这将是不正确的:

/home/parent/child1/child2/filename

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

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

unix awk substr
10个回答
302
投票

使用

awk
根据您可以定义的字段分隔符拆分字段中的行。因此,将字段分隔符定义为
/
你可以说:

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

as

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

39
投票

在这种情况下,最好使用

basename
而不是
awk
:

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

7
投票

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

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

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


5
投票

另一种选择是使用

bash
参数替换

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

4
投票

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

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

很高兴发现有更好的礼仪


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
投票

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

如果您的输入位于 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

0
投票

您可以跳过所有复杂的正则表达式:

 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`

0
投票

刚刚意识到这样更干净

mawk/gawk/nawk

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

'

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

'

filename

-1
投票

您还可以使用:

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

    sed -n 's/.*\/\([^\/]*\)$/\1/p'
© www.soinside.com 2019 - 2024. All rights reserved.