Yishu Fang
Yishu Fang

Reputation: 9978

Using ls, how to list files without printing the extension (the part after the dot)?

Suppose I have a directory with some files:

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

How can I display the result without the file extension(the part following the dot, including that dot)? Like this:

$ <some command>
a
b
e
k
s

Upvotes: 44

Views: 48756

Answers (5)

RMPR
RMPR

Reputation: 3531

If you already know the extension of the file, you can use basename, from the man page:

basename - strip directory and suffix from filenames

Unfortunately, it's mostly useful if you're trying to filter a single extension, in your case the command is:

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

output:

a
b
e
k
s

Upvotes: 1

Paul Parker
Paul Parker

Reputation: 1313

for f in *; do printf "%s\n" ${f%%.*}; done

Why it works?

${string%%substring} Deletes longest match of $substring from back of $string.

This would handle mypackage.pkg.tar.xz --> mypackage for instance.

In contrast:

${string%substring} Deletes shortest match of $substring from back of $string.

That is ${string%substring} would only delete the final extension, i.e. mypackage.pkg.tar.xz --> mypackage.pkg.tar

On a side note, use printf preferentially to echo. The syntax is a little more complex, but it will work on a wider variety of systems.

If you only want to see files, not directories:

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

Upvotes: 1

runlevel0
runlevel0

Reputation: 2973

ls -a | cut -d "." -f 1

man (1) cut

Very handy, the -d switch defines the delimiter and the -f which field you want.

EDIT: Include riverfall's scenario is also piece of cake as cut can start also from the end, though the logic is somewhat different. Here an example with a bunch of files with random names, some with two dots, some with a single dot and some without extension:

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

Using the minus before the field number makes it eliminate all BUT the indicated fields (1,2 in this case) and putting it behind makes it start counting from the end.

This same notation can be used for offset and characters besides of fields (see the man page)

Upvotes: 9

Dyno Fu
Dyno Fu

Reputation: 9044

using sed?

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

Upvotes: 67

jim mcnamara
jim mcnamara

Reputation: 16389

ls | while read fname 
do
    echo ${fname%%.*}
done

Try that.

Upvotes: 15

Related Questions