在bash脚本中使用空格的basename?

时间:2011-08-25 16:48:24

标签: linux bash unix shell scripting

我正在使用bash脚本在/ tmp /中使用文件名创建一个新文件夹,然后将该文件复制到该文件夹​​中。

#!/bin/bash

MYBASENAME="`basename $1`"
mkdir "/tmp/$MYBASENAME"

for ARG in "$@"
    do
        mv "$ARG" "/tmp/$MYBASENAME"

done

行为:

当我输入mymove "/home/me/downloads/my new file.zip"时,它会显示:

mkdir /tmp/my
new
file.zip
mv: rename /home/me/downloads/my new file.zip to /tmp/my\nnew\nfile.zip:

我对所有内容都有很多引用,所以我不明白为什么这不能按预期工作。

另外,如果有多个文件,我有表格循环。我希望根据第一个参数的基本名称将它们全部复制到同一个文件夹中。

5 个答案:

答案 0 :(得分:16)

如果赋值是单个命令替换,则不需要引用命令替换。 shell不会对变量赋值执行分词。

MYBASENAME=$(basename "$1")

只需要。您应该养成使用$()而不是反引号的习惯,因为$()更容易嵌套(它是POSIX,顺便说一下,所有现代shell都支持它。)

PS:你应该尝试编写 bash 脚本。尝试编写 shell 脚本。不同之处在于没有bashisms,zshisms等。就像C一样,可移植性是脚本的理想特性,特别是如果它可以轻松实现的话。你的脚本不使用任何bashisms,所以我写了#!/bin/sh。对于挑选者:是的,我知道,旧的SunOS和Solaris /bin/sh不理解$(),但/usr/xpg4/bin/sh是POSIX shell。

答案 1 :(得分:4)

问题在于

中的$1
MYBASENAME="`basename $1`" 

未引用。请改用:

MYBASENAME="$(basename "$1")"

答案 2 :(得分:2)

你错过了一组引号!

MYBASENAME="`basename \"$1\"`"

这将解决您的问题。

答案 3 :(得分:0)

MYBASENAME="`basename $1`"

应该是

MYBASENAME="`basename "$1"`"

用双引号$1

包裹"$1"

答案 4 :(得分:0)

我只是复制[SOLVED] mv: target `filename' is not a directory中的内容;归功于原始响应者:

将此添加到脚本的开头。它改变了内部领域 仅将分隔符替换为换行符,并且脚本会将空格视为 然后是另一个字符。

#!/bin/bash

IFS='
'

<your script>

此Wikipedia页面介绍了有关特殊Shell变量的更多信息:Internal field separator