【问题标题】:Using ls, how to list files without printing the extension (the part after the dot)?使用 ls,如何列出文件而不打印扩展名(点后的部分)?
【发布时间】:2012-11-20 11:55:59
【问题描述】:

假设我有一个包含一些文件的目录:

$ ls
a.c  b.c  e.c  k.cpp  s.java

如何在没有文件扩展名的情况下显示结果(点后面的部分,包括那个点)?像这样:

$ <some command>
a
b
e
k
s

【问题讨论】:

    标签: bash ls


    【解决方案1】:

    使用 sed?

    ls -1 | sed -e 's/\..*$//'
    

    【讨论】:

    • FWIW,我会使用 ls | sed 's/\(.*\)\..*/\1/' 仅剥离以 last 点开头的部分。 (另外,请注意目录名称中的.,例如 ls ../src
    • ls -1 和 ls 当 ls 的标准输出是管道时表现相同。真的没关系……
    • @rici: sed -e 's/\.[^.]*$//'
    • @anishsane,是的,或者那个。 s:\.[^./]*$:: 会更好。
    【解决方案2】:
    ls | while read fname 
    do
        echo ${fname%%.*}
    done
    

    试试看。

    【讨论】:

    • don't parse ls -- for fname in *; do ...
    • @Glenn - 这是一个正确的方法,是的。 UUOC 概念。我认为OP暗示使用ls。显然,Dyno Hungjun Fu 也是如此。
    • 这就是我一直在寻找的东西!!!哇谢谢你!!!! :))))
    【解决方案3】:
    ls -a | cut -d "." -f 1
    

    人(1)切

    非常方便,-d 开关定义了分隔符,-f 定义了你想要的字段。

    编辑:包括riverfall's 场景也是小菜一碟,因为切割也可以从头开始,尽管逻辑有些不同。这是一个示例,其中包含一堆随机名称的文件,一些有两个点,一些有一个点,一些没有扩展名:

    runlevel0@ubuntu:~/test$ ls
    test.001.rpx  test.003.rpx  test.005.rpx  test.007.rpx  test.009.rpx  testxxx
    test.002.rpx  test.004.rpx  test.006.rpx  test.008.rpx  test_nonum    test_xxx.rtv
    
    
    runlevel0@ubuntu:~/test$ ls | cut  -d "." -f -2
    test.001
    test.002
    test.003
    test.004
    test.005
    test.006
    test.007
    test.008
    test.009
    test_nonum
    testxxx
    test_xxx.rtv
    

    使用减号 before 字段编号使其消除所有但指定的字段(在本例中为 1,2)并将其放在后面使其从末尾开始计数。

    同样的符号可以用于除字段之外的偏移量和字符(参见手册页)

    【讨论】:

    • 文件名可以多于 1 个点,尤其是 rpm 包
    • 谁能告诉我为什么 ls |剪切-d“。” -f -2 > test.txt 不起作用?
    • 不知道伙伴。我不知道你希望看到什么。我假设您知道您必须使用cat 读取文件,对吧?
    【解决方案4】:

    如果您已经知道文件的扩展名,可以使用手册页中的basename

    basename - 从文件名中去除目录和后缀

    不幸的是,如果您尝试过滤单个扩展名,它最有用,在您的情况下,命令是:

    basename -s .c -a $(ls *.c) && basename -s .cpp -a $(ls *.cpp) && basename -s .java -a $(ls *.java)
    

    输出:

    a
    b
    e
    k
    s
    

    【讨论】:

      【解决方案5】:
      for f in *; do printf "%s\n" ${f%%.*}; done
      

      Why it works?

      ${string%%substring} 从 $string 后面删除 $substring 的最长匹配项。

      这将处理mypackage.pkg.tar.xz --> 例如mypackage

      相比之下:

      ${string%substring} 从 $string 后面删除 $substring 的最短匹配项。

      ${string%substring} 只会删除最后的扩展名,即 mypackage.pkg.tar.xz --> mypackage.pkg.tar

      附带说明,优先使用printf 而不是echo。语法稍微复杂一些,但它适用于更广泛的系统。

      如果您只想查看文件,而不是目录:

      for f in *; do if [[ -f ${f} ]]; then printf "%s\n" ${f%%.*}; fi; done
      

      【讨论】:

        猜你喜欢
        • 2010-11-29
        • 2019-01-06
        • 2017-02-06
        • 1970-01-01
        • 2014-12-26
        • 1970-01-01
        • 2020-05-14
        • 2013-03-30
        • 1970-01-01
        相关资源
        最近更新 更多