mv command works individually on command line but not through script

时间:2015-07-28 16:13:02

标签: bash shell unix sh

I have a fodler that contains file names that have spaces in them.

I have made a script that replaces the spaces and creates the new file name with _ instead of " " (space) and ran the mv command in the for loop.

This has not worked in script and giving me the below message.

   Usage: mv [-I] [ -d | -e] [-i | -f] [-E{force|ignore|warn}] [--] src target
   or: mv [-I] [-d | -e] [-i | -f] [-E{force|ignore|warn}] [--] src1 ... srcN directory

But if i debug the shell script and extract the mv command individually and run it,it does work fine without any issues.

The command that is generated looks like

   mv "abc  ddd eee.txt" abc_ddd_eee.txt

Could you please advise why the command when typed on unix box worked fine and not via script ?

Entire script:

     for i in * 
      do 
       v1=$(echo $i|sed -e 's/^/"/g' -e 's/$/"/g' )
       v2=$(echo $v1|sed 's/ /_/g'|
             awk -F "[-.]" '{print $2,"_",$1,".",$3}'|
             sed 's/ //g'|
             sed -e 's/^_//g' -e 's/"$//g'|
             sed 's/"//2' )        
       mv $v1 $v2

      done

2 个答案:

答案 0 :(得分:5)

In native bash, with no external tools other than mv itself:

for i in *; do
    # change all spaces to underscores
    v2=${i// /_}

    # split into pieces on . and _ characters, and reassemble after 
    IFS='._' read -r first second rest <<<"$v2" && {
      v2="${second}_${first}.${rest}"
    }

    # remove any leading underscore
    v2=${v2#_}

    # rename
    mv -- "$i" "$v2"
done

This is vastly more efficient than setting up a new pipeline running sed and awk once for each filename processed.

答案 1 :(得分:4)

There's no need to add quotes around the name, just quote the variables. Do:

for i in * 
do 
   v2=$(echo "$i" | sed 's/ /_/g' | awk -F "[-.]" '{print $2,"_",$1,".",$3}' | sed 's/^_//')     
   mv "$i" "$v2"
done