Tell `ls` to print only the base filename

85,855

Solution 1

While xargs -0 is intended to be used for input delimited by \0 (like find -print0), ls has no such option to delimit its output in this way.

However,

ls -1 /path/glob | tr '\n' '\0' | xargs -0 -n 1 basename

would do the trick to convert newlines to nulls along the way. This then allows xargs to work with names that have spaces.

EDIT: added -n 1 to xargs

Solution 2

I use this:

ls | tr '\n' '\n'

It gives a list like:

file1.mp3
file2.mp3
file3.mp3
...

Solution 3

ls -1 <path> | sed 's#.*/##'

Solution 4

Both GNU basename and FreeBSD basename accept an -a argument allowing you to pass multiple paths to the command. This works great with shell globbing.

basename -a /path/glob*

Solution 5

awk solution:

ls -1 /path/glob | awk -F'/' '{print $NF}'
Share:
85,855

Related videos on Youtube

Sridhar Ratnakumar
Author by

Sridhar Ratnakumar

Updated on September 17, 2022

Comments

  • Sridhar Ratnakumar
    Sridhar Ratnakumar over 1 year

    This is the default behaviour of ls

    ls /net/nas/data/languages/pypm/sites/rex/free/2.6/*/pool/v/vi/virtual*1.4.4*pypm
    /net/nas/data/languages/pypm/sites/rex/free/2.6/linux-x86/pool/v/vi/virtualenv-1.4.4_linux-x86_2.6_1.pypm
    /net/nas/data/languages/pypm/sites/rex/free/2.6/linux-x86_64/pool/v/vi/virtualenv-1.4.4_linux-x86_64_2.6_1.pypm
    /net/nas/data/languages/pypm/sites/rex/free/2.6/macosx/pool/v/vi/virtualenv-1.4.4_macosx_2.6_1.pypm
    /net/nas/data/languages/pypm/sites/rex/free/2.6/win32-x86/pool/v/vi/virtualenv-1.4.4_win32-x86_2.6_1.pypm
    

    How do I make ls print only the basename? Like:

    ls $OPTIONS /net/nas/data/languages/pypm/sites/rex/free/2.6/*/pool/v/vi/virtual*1.4.4*pypm
    virtualenv-1.4.4_linux-x86_2.6_1.pypm
    virtualenv-1.4.4_linux-x86_64_2.6_1.pypm
    virtualenv-1.4.4_macosx_2.6_1.pypm
    virtualenv-1.4.4_win32-x86_2.6_1.pypm
    

    Note: I prefer shell globbing over using find as /net/nas/data/languages/pypm/sites/rex/free contains huge number of files and directories.

    • akira
      akira almost 14 years
      you prefer shell globbing OVER using find when the directory contains lots of files? typo??
  • Steve Folly
    Steve Folly over 14 years
    -1: ls can't delimit names by \0 which is what xargs -0 is looking for.
  • Sridhar Ratnakumar
    Sridhar Ratnakumar over 14 years
    This does not work for me: basename: extra operand \033[0m/net/nas/data/languages/pypm/sites/rex/free/2.6/macos‌​x/pool/v/vi/virtuale‌​nv-1.4.4_macosx_2.6_‌​1.pypm\033[0m'`
  • Steve Folly
    Steve Folly over 14 years
    @Sridhar: you might need the -n 1 you suggested elsewhere as an option to xargs ? (answer edited)
  • Sridhar Ratnakumar
    Sridhar Ratnakumar over 14 years
    Unfortunately, -printf option is not available in MacOSX version of find.
  • Sridhar Ratnakumar
    Sridhar Ratnakumar over 14 years
    Although I personally prefer my own answer (as I almost never have to deal with spaces in filenames), I will mark this as the answer for it handles spaces as well.
  • Ryan Bright
    Ryan Bright over 14 years
    Good call; apologies for the oversight. I've updated the answer.
  • intuited
    intuited almost 14 years
    If the mac version of xargs supports the -d (delimiter) option, you can do ls ... | xargs -d '\n' -n 1 basename.
  • HikeMike
    HikeMike over 11 years
    This is essentially the same as ls -1 (and coloring disabled), as ls implies those when not writing to a terminal. It looks like you're missing the point a bit, as the issue is stripping the dir name swhen specifying ls path arguments using wild cards. Try ls -d "$PWD/"* | tr '\n' '\n' to see what the actual issue is.
  • Mmmh mmh
    Mmmh mmh over 9 years
    AH! Finally something that works with multiple arguments!
  • slhck
    slhck almost 7 years
    -1 – not sure why people keep upvoting this answer. Not only does it do the same thing as ls -1, it also does not work when globs have been used, as Daniel Beck pointed out.
  • SineSwiper
    SineSwiper over 4 years
    -1 - This is the same as ls -1, and only works in the current directory, not with a path like ls path/*.
  • Scott - Слава Україні
    Scott - Слава Україні over 3 years
    (1) Have you tried this?  (2) Try it with directories and wildcards on the command line, like in the question; e.g., ls vacation/*.jpg.  (3) If you still think this is a good answer, try it with files with spaces in their names.
  • Cymatical
    Cymatical over 2 years
    Would have thought just --- $ ls | xargs basename --- but found it problematic. This works.
  • Cymatical
    Cymatical over 2 years
    Recall reading ls command is bad for xargs, and find command is better.
  • Cymatical
    Cymatical over 2 years
    Note comment below for answer below - not sure why people keep upvoting this answer (ls | tr '\n' '\n' ) ... not only does it do the same thing as ls -1, it also does not work when globs have been used, as Daniel Beck pointed out. "
  • verboze
    verboze about 2 years
    much more performant than the accepted basename solution
  • verboze
    verboze about 2 years
    this works, but I wouldn't run this on a directory with hundreds or thousands of files. The awk/sed solutions are much more performant.