104

ls /home/user/new/*.txt prints all txt files in that directory. However it prints the output as follows:

[me@comp]$ ls /home/user/new/*.txt
/home/user/new/file1.txt    /home/user/new/file2.txt    /home/user/new/file3.txt

and so on.

I want to run the ls command not from the /home/user/new/ directory thus I have to give the full directory name, yet I want the output to be only as

[me@comp]$ ls /home/user/new/*.txt
file1.txt    file2.txt    file3.txt 

I don't want the entire path. Only filename is needed. This issues has to be solved using ls command, as its output is meant for another program.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Ashish
  • 1,153
  • 2
  • 7
  • 12

14 Answers14

170

ls whateveryouwant | xargs -n 1 basename

Does that work for you?

Otherwise you can (cd /the/directory && ls) (yes, parentheses intended)

fge
  • 119,121
  • 33
  • 254
  • 329
65

No need for Xargs and all , ls is more than enough.

ls -1 *.txt

displays row wise

Yan Foto
  • 10,850
  • 6
  • 57
  • 88
VRVigneshwara
  • 1,009
  • 8
  • 10
  • 34
    This is not the correct if you read OP carefully. This only works if you are in that directory. – Barney Szabolcs Aug 29 '16 at 12:16
  • 3
    Works perfectly! Thanks @VRVigneshwara! `ls -1 bin/` list entries inside bin/ directory without path on Linux Debian. – Zeke Fast Nov 22 '17 at 11:48
  • This will cause trouble with lots (and lots) of files and also directories ending in `.txt`, and needs [globbing](https://en.wikipedia.org/wiki/Glob_%28programming%29 "glob (programming)") to be active in your shell. – ckujau Mar 28 '20 at 23:53
18

There are several ways you can achieve this. One would be something like:

for filepath in /path/to/dir/*
do
    filename=$(basename $filepath)

    ... whatever you want to do with the file here
done
Vishrant
  • 15,456
  • 11
  • 71
  • 120
pgl
  • 7,551
  • 2
  • 23
  • 31
17

Use the basename command:

basename /home/user/new/*.txt
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
Dwayne
  • 207
  • 2
  • 5
  • basename (GNU coreutils) 9.3 (packaged for arch linux) does not support multiple file parameters without the `-a` option. I think this applies to most(?) other versions and distros as well. – Sparr Jul 01 '23 at 22:44
11

(cd dir && ls)

will only output filenames in dir. Use ls -1 if you want one per line.

(Changed ; to && as per Sactiw's comment).

mrpraline
  • 111
  • 1
  • 3
  • 1
    Using ';' in place of '&&' for chaining of commands will be buggy in this case as it would return some output in case of non existing 'dir' as well i.e. list files from current working directory from where you are executing this command. E.g. (cd fake_dir ; ls) would list files from current directory even if no such fake_dir exists, which would be incorrect. – sactiw Jun 25 '19 at 14:30
9

you could add an sed script to your commandline:

ls /home/user/new/*.txt | sed -r 's/^.+\///'
zuloo
  • 1,310
  • 1
  • 8
  • 12
  • exactly what I was looking for; I was trying the "ls -1 /path/*" and wanting the path to not be listed. This nailed it !! I did not want to go the CD route in case I needed to stay in the current directory. Saved me having to note it and then return to it after the above command. Awesome. – Dee Aug 08 '22 at 07:19
8

A fancy way to solve it is by using twice "rev" and "cut":

find ./ -name "*.txt" | rev | cut -d '/' -f1 | rev
John Rumpel
  • 4,535
  • 5
  • 34
  • 48
6

The selected answer did not work for me, as I had spaces, quotes and other strange characters in my filenames. To quote the input for basename, you should use:

ls /path/to/my/directory | xargs -n1 -I{} basename "{}"

This is guaranteed to work, regardless of what the files are called.

Addison
  • 7,322
  • 2
  • 39
  • 55
3

I prefer the base name which is already answered by fge. Another way is :

ls /home/user/new/*.txt|awk -F"/" '{print $NF}'

one more ugly way is :

ls /home/user/new/*.txt| perl -pe 's/\//\n/g'|tail -1
Vijay
  • 65,327
  • 90
  • 227
  • 319
1

just hoping to be helpful to someone as old problems seem to come back every now and again and I always find good tips here.

My problem was to list in a text file all the names of the "*.txt" files in a certain directory without path and without extension from a Datastage 7.5 sequence.

The solution we used is:

ls /home/user/new/*.txt | xargs -n 1 basename | cut -d '.' -f1 > name_list.txt
Mauri
  • 11
  • 2
  • basename can remove the suffix for you as well (you specify the suffix to remove as the second argument). your command would become: ```ls /home/user/new/*.txt | xargs -n 1 -J % basename % .txt ``` – welch Feb 05 '19 at 19:59
0

There are lots of way we can do that and simply you can try following.

ls /home/user/new | tr '\n' '\n' | grep .txt

Another method:

cd /home/user/new && ls *.txt
Chaminda Bandara
  • 2,067
  • 2
  • 28
  • 31
0

Here is another way:

ls -1 /home/user/new/*.txt|rev|cut -d'/' -f1|rev
0

You could also pipe to grep and pull everything after the last forward slash. It looks goofy, but I think a defensive grep should be fine unless (like some kind of maniac) you have forward slashes within your filenames.

ls folderpathwithcriteria | grep -P -o -e "[^/]*$"
bfontaine
  • 18,169
  • 13
  • 73
  • 107
-1

When you want to list names in a path but they have different file extensions.

me@server:/var/backups$ ls -1 *.zip && ls -1 *.gz

JKE
  • 19
  • 3