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.

  • 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 '18 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 '18 at 14:47
18

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 {} \;
  • Ok this way is perfect for me as well. – рüффп Apr 15 '14 at 13:46
  • 2
    Also see the -maxdepth option. – user26112 Apr 15 '14 at 20:11
13

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'
10

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.

  • Spaces won't be an issue either. – terdon Apr 15 '14 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 '14 at 15:14
  • Or even printf '%s\0' *.jar to eliminate whitespace issues (although this is not the Q). – Graeme Apr 15 '14 at 15:16
5

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.

  • 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 '17 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*
  • 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 '14 at 3:14
  • grep -v jar* would filter out results with file named like your quoted example. – joshi.mohit86 Apr 16 '14 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 '14 at 3:39
  • No, it would display files like mylib_2.jar and filter out files like list-of-jars.txt. – joshi.mohit86 May 13 '14 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 '14 at 11:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.