42

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

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

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

$ <some command>
a
b
e
k
s
4

5 回答 5

62

使用 sed?

ls -1 | sed -e 's/\..*$//'
于 2012-12-03T01:56:52.883 回答
15
ls | while read fname 
do
    echo ${fname%%.*}
done

试试看。

于 2012-12-03T01:56:22.873 回答
8
ls -a | cut -d "." -f 1

男 (1) 切

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

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

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

在字段编号之前使用减号可以消除所有但指定的字段(在这种情况下为 1,2)并将其放在后面使其从末尾开始计数。

除了字段之外,此相同的表示法还可用于偏移量和字符(请参阅手册页)

于 2016-05-27T08:37:19.593 回答
1

如果您已经知道文件的扩展名,则可以使用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
于 2020-08-07T13:55:33.647 回答
0
for f in *; do printf "%s\n" ${f%%.*}; done

为什么它有效?

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

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

相比之下:

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

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

在旁注中,printf优先使用 to echo。语法稍微复杂一些,但它适用于更广泛的系统。

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

for f in *; do if [[ -f ${f} ]]; then printf "%s\n" ${f%%.*}; fi; done
于 2020-02-29T21:24:59.923 回答