How can I use a wildcard to match just files, not directories?

8,584

Solution 1

With zsh, use glob qualifiers:

mv home*(.) dst 

moves only regular files.

While

mv home*(^/) dst 

moves files of any type except directories.

mv home*(^-/) dst

would also exclude symlinks to directories.

Solution 2

You can use find. The following should work.

find . -name home\* -type f -maxdepth 1 -exec mv {} /home/homeLife/. \;

Solution 3

You can use bash extended globs:

shopt -s extglob                ## activate extglogs if not yet done
mv  home!(*Life) homeLife/      ## !(p1|...) = anything except one of the patt

Solution 4

Portably you can prune your glob match list:

set --; cd /home
for f in ./home*
do  [ ! -L "$f" ] && 
      [ -f "$f" ] && 
      set "$@" "$f"
done
[ "$#" -eq 0 ] || mv "$@" ./homeLife

Solution 5

You're close already. To move your files home1, home2, home3 use the globbing pattern home?.

mv home? /home/homeLife/

The ? denotes any single character, while the * denotes any amount of characters (including none).

Share:
8,584

Related videos on Youtube

Michael Bruce
Author by

Michael Bruce

Updated on September 18, 2022

Comments

  • Michael Bruce
    Michael Bruce over 1 year

    I have a folder called home/homeLife

    I have a file called home1 home2 and home3 stored in /home

    I want to move all files that start with home* to home/homeLife/..

    I typed

    mv home* /home/homeLife
    cannot move homeLife into subdirectory of itself
    

    My question: How can I exclude directories?

    • heemayl
      heemayl about 9 years
      Do you have a file called home1 home2 and home3 or files called home1, home2, home3?
    • Janis
      Janis about 9 years
      I gave an answer below to solve your task. The question to exclude directories is a bit less simple; I propose to use the find -type f command. (I'll provide details on request if necessary.)
    • drs
      drs about 9 years
      regardless of the error message, your command should have succeed; it skipped the directory homeLife, because, at it says, it cannot move homeLife into itself.
    • Michael Bruce
      Michael Bruce about 9 years
      heemay- No. I just made them with touch. I am working on a book called The Linux Command Line. They are empty files. Sometimes I just make up random tasks to learn things.
    • Michael Bruce
      Michael Bruce about 9 years
      Hmm... i did not check yet if it, in fact did perform the move. Ill look immediately. Janis. Yes. I would like more details. I am all about understanding Linux. Thank you for the command find -type f
  • heemayl
    heemayl about 9 years
    One point, if the file name really is home1 home2 and home3 then you better use mv home?* /home/homeLife/ ..this will work for both circumstances..
  • Janis
    Janis about 9 years
    heemayl, that will not address the issue since your pattern will also match homeLife which was the one to avoid with the globbing expression.
  • heemayl
    heemayl about 9 years
    my bad..did not see it closely.. :)
  • Michael Bruce
    Michael Bruce about 9 years
    echo $SHELL shows zsh... I didn't realize I was using that. (NEWB). Anyway your commands are perfect. I deleted all files in a current working dir with # rm *(.) thanks again!
  • Olivier Dulac
    Olivier Dulac about 9 years
    +1 for portability (there are a lot of very old systems out there!)
  • Stéphane Chazelas
    Stéphane Chazelas about 9 years
    Note that it moves regular files and symlinks to regular files.
  • mikeserv
    mikeserv about 9 years
    @StéphaneChazelas - is that what you were talking about? Weird that mv doesn't seem to have any -LHP switches spec'd.
  • Arul
    Arul about 9 years
    In my example above, I am using '\' to avoid shell interpreting the wildcard. Quoting your wildcard like "home*" will work as well.
  • Mark Lakata
    Mark Lakata over 4 years
    The -maxdepth 1 option needs to come first, otherwise find will issue a warning.