12

I am in a bash script and I want to get the list of all files (let say all jar files). I execute the command ls -1 lib/*.jar and I get the output:

lib/mylib_1.jar
lib/mylib_2.jar
...

Is there any option to have the following output:

mylib_1.jar
mylib_2.jar
...

Making cd lib before is not an option as I am in a loop and need to be in the parent folder for the actions I want to do inside the loop.

I tried to find information by typing man ls but I did not find any solution.

A solution with another command would be good as long I can pipe it to my ls command or self sufficient.

2
  • What are you doing with the names of those files? Are you just listing them to the terminal, or are you passing them to another program or script (individually or as a list)? The correct way to handle this depends on how the filenames are used.
    – Kusalananda
    Oct 18, 2018 at 7:03
  • The idea was to do some statistics about third party libs on a multi-module java project. I just wanted the list and make a sort and uniq after
    – рüффп
    Oct 19, 2018 at 14:47

7 Answers 7

19

Instead of parsing ls you should use find instead. Then you can also execute basename on each file to strip the leading directories:

find lib/ -name '*.jar' -exec basename {} \;
2
  • Ok this way is perfect for me as well.
    – рüффп
    Apr 15, 2014 at 13:46
  • 4
    Also see the -maxdepth option.
    – user26112
    Apr 15, 2014 at 20:11
16

With GNU find there is no need to run basename for every single file, this will be much faster (especially if there is a lot of files):

find lib -name '*.jar' -printf '%P\n'
11

How about (cd lib && echo *.jar), assuming that you don't have whitespace or special characters in the file names. Parent script never changes directory.

3
  • Spaces won't be an issue either.
    – terdon
    Apr 15, 2014 at 14:39
  • This is a good idea and will probably be the fastest option. I would do printf '%s\n' *.jar to get each file on a different line though.
    – Graeme
    Apr 15, 2014 at 15:14
  • Or even printf '%s\0' *.jar to eliminate whitespace issues (although this is not the Q).
    – Graeme
    Apr 15, 2014 at 15:16
6

As Josh Jolly said in his answer, you should never parse ls, use the approach in his answer instead. Still, here's an awk solution to remove paths from file names, just don't use it with ls:

find . | awk -F'/' '{print $NF}'

The -F'/' sets the field separator to / which means that the last field, $NF, will be the file name.

1

find is probably the way to go, but if you really, really do (you don't) want to strip off lib/ from ls -1, you can use sed:

$ ls -1 lib/*.jar | sed 's#^lib/##'
mylib_1.jar
mylib_2.jar
0

You can do this using xargs with a --max-args (or the shorter alias -n) parameter:

ls --quoting-style=c -1 lib/*.jar | xargs --max-args 1 basename ls --quoting-style=c -1 lib/*.jar | xargs -n 1 basename

Note that we use --quoting-style=c to make sure spaces in filenames do not screw up xargs.

1
  • I didn't notice that. Thank you! Found this gem on another stack exchange. You can introduce quotes to ls results with --quoting-style=c. So the resulting full command would be: ` ls --quoting-style=c -1 lib/*.jar | xargs --max-args 1 basename`
    – yoni
    May 5, 2017 at 22:48
-1

An alternative way solve your query is to list all the files using ls -R. Combine the output of ls command with grep to list only .jar files. You can use following command to do the same for your query:

ls -R lib | grep jar| grep -v jar*
5
  • This would fail badly if there were a subdirectory that also contains jar files, or a file named for example "list-of-jars.txt".
    – Jules
    Apr 16, 2014 at 3:14
  • grep -v jar* would filter out results with file named like your quoted example. Apr 16, 2014 at 6:18
  • true. it would also filter out all the intended files. Now I look at it again, I can see no circumstances where the command you suggest would actually produce any output at all...
    – Jules
    Apr 19, 2014 at 3:39
  • No, it would display files like mylib_2.jar and filter out files like list-of-jars.txt. May 13, 2014 at 10:07
  • No, it doesn't. I just tried it. find development -name '*.jar' | wc -l -> 70. ls -R development | grep jar| grep -v jar* -> no output at all.
    – Jules
    May 14, 2014 at 11:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .