0

Below is a small extract of my code for you to have a better visibilty on my problem. As each file in the directory enters the loop, the value of em is extracted from the filename and compared with the declared em values for the next actions to be executed. After executing my code, I noticed that my first condition works but when it comes out from Em1 directory, the second condition is not more verified because I opened the Em2 directory and it was empty meanwhile I have files with em2 value. So i wish to know what is wrong

em1="first"
em2="second"
for file in *;
do
em=$( echo "$file" | awk -F'[.-]' '{print $1}' )
if [[ "$em" == "$em1" ]];
 then
   cd Em1                    #directory to execute action
   month_range               #function for action
   cd_ret                    #function to come back to current directory
elif [[ "$em" == "$em2" ]];
  then
   cd Em2
   month_range
   cd_ret
else
  echo "Nothing to do"
fi
done
2
  • Remove the $ from the for statement (for file in ...). If that's not the problem, I'd recommend putting set -x before this section so it prints an execution trace -- inspect that and see if it differs from what you expect. Commented Oct 2, 2021 at 9:16
  • 2
    You're referring to a function called cd_ret which doesn't exist in the shown code. If it doesn't exist, that might be a problem. If you're just not showing it, then it's hard for any readers to check if there's a problem within it. Commented Oct 2, 2021 at 9:28

1 Answer 1

6

You need to use a variable's name in the for loop header. You used $file in your original question, i.e., the variable file's value.

You are also doing things a bit complicated. To run a command with a temporarily changed working directory, you may use a sub-shell.

( cd Em1 && month_range )

The working directory outside of the sub-shell is not affected by the cd inside the sub-shell. It's unclear what your cd_ret function is doing, so that's another possible source of errors. If you can't do it this way, for example, if month_range is setting variables that need to be visible in the original scope, then use

cd Em1 && { month_range; cd -; }

The above would cd into Em1, run the month_range function, and cd back, assuming month_range does not do further calls to cd. If month_range does use cd, then save the current working directory in a variable and use that instead.

wd=$PWD; cd Em1 && { month_range; cd "$wd"; }

The above assumes that month_range does not change or unset the wd variable.

Your use of awk is problematic as filenames on Unix technically may contain newline characters. It would be better to use a parameter substitution.

em=${file%%[.-]*}

The above chops off the value $file at first - or . character and assigns the resulting string to the variable em.

This leaves you with the following:

em1=first
em2=second

for file in *; do
        em=${file%%[.-]*}

        if [ "$em" = "$em1" ]; then
                ( cd Em1 && month_range )
        elif [ "$em" = "$em2" ]; then
                ( cd Em2 && month_range )
        else
                echo 'Nothing to do'
        fi
done

or

em1=first
em2=second

for file in *; do
        em=${file%%[.-]*}

        case $em in
                "$em1") ( cd Em1 && month_range ) ;;
                "$em2") ( cd Em2 && month_range ) ;;
                *) echo 'Nothing to do'
        esac
done

or, without extracting em from $file at all,

em1=first
em2=second

for file in *; do
        case $file in
                "$em1"[.-]*) ( cd Em1 && month_range ) ;;
                "$em2"[.-]*) ( cd Em2 && month_range ) ;;
                *) echo 'Nothing to do'
        esac
done

or using bash syntax,

em1=first
em2=second

for file in *; do
        if [[ $file == "$em1"[.-]* ]]; then
                ( cd Em1 && month_range )
        elif [[ $file == "$em2"[.-]* ]]; then
                ( cd Em2 && month_range )
        else
                echo 'Nothing to do'
        fi
done

If this then does what you intend depends on the month_range function or script.

2
  • The code cd Em1 && { month_range; cd -; } actually works for me. It goes in the Em1 directory performs month range and comes back to the current working directory without having to use my function cd_ret and same for Em2. cd_ret was just useless. Commented Oct 5, 2021 at 8:40
  • @NgouabaRosalie What about the simpler ( cd Em1 && month_range )? If month_range is a script or function that does not need to change the current environment (set variables etc.), then this would be simpler code. Commented Oct 5, 2021 at 8:50

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.