【问题标题】:Get last field using awk substr使用 awk substr 获取最后一个字段
【发布时间】:2013-07-29 02:18:02
【问题描述】:

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

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

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

/home/parent/child1/child2/filename

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

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

【问题讨论】:

  • 正如有人指出的那样,使用basename 是官方的做法,使用awk 是不好的。 :D

标签: unix awk substr


【解决方案1】:

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

【讨论】:

  • 完美运行。我没有考虑 $NF 变量。感谢您立即提供简单有效的答复。
  • 倒数第二个,使用$(NF-1)
  • 正在编写一个脚本来处理一些 docker 命令,这成功了。谢谢!
【解决方案2】:

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

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

【讨论】:

  • @Mari F.Y.I dirname 做相反的事情并剥离文件而不是路径。
【解决方案3】:

另一种选择是使用bash parameter substitution

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

【讨论】:

    【解决方案4】:

    你也可以使用:

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

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

    【讨论】:

    • 此时没有人赞成这个答案,可能是因为它比较丑:)
    【解决方案5】:

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

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

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

    【讨论】:

    • 谢谢。这帮助我获得了最后一个领域。 perl -F"/" -lane 'print $F[-2]' 输入
    • 从管道输入接收时这对我有用。完全忘记了 perl。
    【解决方案6】:

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

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

    【讨论】:

      【解决方案7】:

      我知道我迟到了 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
      

      【讨论】:

        【解决方案8】:

        我知道,好像晚了 5 年,感谢所有建议,我以前是这样做的:

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

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

        【讨论】:

          猜你喜欢
          • 2013-07-30
          • 2022-01-05
          • 2016-05-06
          • 2012-09-19
          • 1970-01-01
          • 2018-07-31
          • 1970-01-01
          • 2014-03-21
          相关资源
          最近更新 更多