I am writing a bash script which will move files/directories from existing directory path to another directory path. but I am not able to skip some extensions files while using for loop with if condition statements. My script is running without error but it wont skip the required extension files which I have specified in if condition instead it moves the all files and directories. below is the script I am trying to create for same.

please guide me where I am doing it wrong.

Below is what I am trying to do.

#!/bin/env bash

#moving home profile data to another location
echo "Moving Desktop Files"
for m in $path
      link=$(basename -s .lnk ${m})
      desktop=$(basename -s .desktop ${m})
      if [[  "${link}.lnk" == "${m}" ]] || [[ "${desktop}.desktop" == "${m}" ]]
                echo "skipping link and desktop extension files"
mv -n "$m"  /home/$USER/CoreData/HOME/Desktop/


  • rsync has options to exclude files based on patterns such as name elements. Would that be an option? You would just need to remove the complete source files afterwards, as rsync is a tool to copy, not move.
    – AdminBee
    Commented Dec 18, 2020 at 10:53
  • thank you for your suggestion , but my concern is about the script not the way to copy/move files . I am trying to skip files with some specific extensions as mentioned in script but when I execute the script all files are moves in to the specified path . why it is not skipping files with given extensions.
    Commented Dec 18, 2020 at 11:05

1 Answer 1


You're matching the filename suffixes in a very roundabout way, and you have written your loop in a way that disqualifies it from working on files with spaces in their names.

The main issue relating to your if statement is that $m is a pathname, containing directory path elements, while $desktop and $link, if interpreted as filenames, have no directory path elements.

Suggestions for safer code:


for name in "$HOME/Desktop"/*; do
    if [[ $name == *.lnk ]] || [[ $name == *.desktop ]]; then
        printf 'Skipping "%s"\n' "$name"
        mv -n -- "$name" "$HOME/CoreData/HOME/Desktop"

This uses (globbing) pattern matching with == within [[ ... ]] in bash.

If you really want to do the globbing of names separately and save them in a variable, then use an array for this:

names=( "$HOME/Desktop"/* )

for name in "${names[@]}"; do ... done

Note that the quoting above is important, to maintain the integrity of individual pathnames.

Or, using a case ... esac statement in /bin/sh:


for name in "$HOME/Desktop"/*; do
    case $name in
            printf 'Skipping "%s"\n' "$name"
            mv -n -- "$name" "$HOME/CoreData/HOME/Desktop"

Again, would you want to do the globbing separately:

set -- "$HOME/Desktop"/*

for name do ... done

This uses the positional parameters rather than a named array. The sh shell does not support named arrays.

Alternatively, use rsync:

rsync --archive --verbose \
    --exclude='*.lnk' \
    --exclude='*.desktop' \
    "$HOME/Desktop/" "$HOME/CoreData/HOME/Desktop"

(then remove "$HOME/Desktop" if you wish)

  • First of all thank you for the solution & explanation on my script. I have still one question if you don't mind. as you said matching a file extension in very roundabout way what that mean. second you said script will disqualify but I have one another script with little changes that works fine and this script also moves all the directories it has in $HOME/Desktop directory I am just curious to know why the continue command does not respond as condition is correct.
    Commented Dec 18, 2020 at 11:55
  • @ITGUYAKAY I mentioned this in my second paragraph. You are comparing something that is a filename ($desktop and $link) to something that is a filename with a directory path ($m). The condition is therefore false and the continue statement is not executed.
    – Kusalananda
    Commented Dec 18, 2020 at 12:00
  • got it 😀 actually I didn't refresh the page. 😜
    Commented Dec 18, 2020 at 12:02

You must log in to answer this question.

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