从文件执行复制命令

从文件执行复制命令

我有一个DE_CopyOldToNew.txt文件,其中包含一大堆复制命令,用于将旧文件名复制到新文件名。

该文件包含如下行:

cp /migrationfiles/Company\ Name\ GmbH/2014.138_Old\ File\ Name.pdf /appl/data/docs/202403/DE_2014.138_NewFile_1.pdf
cp /migrationfiles/Company\ Name\ GmbH/2014.139_Old\ File\ Name.pdf /appl/data/docs/202403/DE_2014.139_NewFile_1.pdf

在我的 shell 脚本中,我迭代每一行并执行它。

echo "Start!"
while read -r line
do
  command "$line"
done < /tmp/DE_CopyOldToNew.txt

执行脚本时,我会为读取的每一行获取以下内容......

 : No such file or directory6: cp /migrationfiles/Company\ Name\ GmbH/2014.138_Old\ File\ Name.pdf /appl/data/docs/202403/DE_2014.138_NewFile_1.pdf

当从提示符下手动执行行时,它可以正常工作,不会出现错误......

答案1

问题是您正在将整行读入shell 变量line,然后使用引号(即 as "$line")。

虽然在使用 shell 变量时,特别是在处理(如您所做的)包含空格或其他“有问题”字符的文件名时,双引号通常是正确的,但在这种情况下,这意味着整条线cp由命令组成及其论点在您的语句中被视为单个 shell 标记command

这意味着在循环中,您没有执行cp带有参数/migrationfiles/Company\ Name\ GmbH/2014.138_Old\ File\ Name.pdf和 的命令/appl/data/docs/202403/DE_2014.138_NewFile_1.pdf,但 shell 尝试运行名为的可执行文件

cp /migrationfiles/Company\ Name\ GmbH/2014.138_Old\ File\ Name.pdf /appl/data/docs/202403/DE_2014.138_NewFile_1.pdf

其中用于分隔命令和参数的空格被解释为命令名称的一部分。这个可执行文件当然不存在。

您可以做的是将这些行读入三个变量,如下所示:

echo "Start!"
while read cmd arg1 arg2
do
  command "$cmd" "$arg1" "$arg2"
done < /tmp/DE_CopyOldToNew.txt

假设结构始终采用示例中所示的形式。

笔记这个read命令才不是包含该-r选项,因为这会禁止将\后面的空格解释为转义字符,但我们需要 shell 在这里执行此操作。

答案2

你说,

我有一个DE_CopyOldToNew.txt文件,其中包含一大堆复制命令,用于将旧文件名复制到新文件名。

...并且您说您要执行这些cp命令。

您很幸运,因为您有一个 shell 脚本,即一个包含一组由 shell 按顺序执行的命令的文件。您需要做的就是让 shell 执行脚本中的命令:

sh DE_CopyOldToNew.txt

这将启动sh一个基本 shell,并让它逐个命令执行文件的内容。

答案3

我不会让TXT文件做任何动作,而是将其视为数据源,因此使用脚本不仅可以执行需要执行的内容,还可以作为对数据的控制:

# Read each line of the file
while IFS= read -r line; do
    # Get the files using awk with ' /' as separator.
    # $line could have escaped spaces with '\ ' so we use parameter substitution →
    # → to substitute them to unescaped spaces: "${line//\\ / }".
    source_file=$(awk -F' /' '{ print "/"$2 }' <<<"${line//\\ / }") # source file
    destination=$(awk -F' /' '{ print "/"$3 }' <<<"$line") # destination
    
    # For example you can control that the source file exists
    if [[ ! -f "$source_file" ]]; then
        echo "The file $source_file does not exists!"
        exit
    fi
    
    # The cp command is executed here
    cp "$source_file" "$destination"
done </tmp/DE_CopyOldToNew.txt

相关内容