mv 命令在命令行上单独运行,但不能通过脚本运行

mv command works individually on command line but not through script

我有一个 fodler,其中包含包含 space 的文件名。

我制作了一个脚本来替换 spaces 并使用 _ 而不是 " " (space) 创建新文件名,并且 运行 for 中的 mv 命令循环。

这在脚本中不起作用并给我以下消息。

   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

但是如果我调试 shell 脚本并单独提取 mv 命令和 运行 它,它确实可以正常工作,没有任何问题。

生成的命令看起来像

   mv "abc  ddd eee.txt" abc_ddd_eee.txt

你能告诉我为什么在 unix 机器上输入的命令运行良好而不是通过脚本运行吗?

整个脚本:

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

      done

不需要在名称周围添加引号,只需引用变量即可。做:

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

在原生 bash 中,除了 mv 本身之外没有任何外部工具:

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

这比为每个处理的文件名设置一次新管道 运行 sedawk 效率要高得多。