在 cp 循环期间覆盖的文件

Posted

技术标签:

【中文标题】在 cp 循环期间覆盖的文件【英文标题】:Files overwritten during cp loop 【发布时间】:2015-06-26 15:29:15 【问题描述】:

我正在尝试将文件夹 A(主文件夹)中的 4 个文件复制到文件夹 A 中的所有子文件夹 (1000) 中。为此,我使用了:

for i in *;     
do       
cp  File1.bash $i      
cp  File2.sh $i         
cp  File3.R $i        
cp  File4.R $i       
done  

不幸的是,目标目录中 cp 之后的所有文件的内容都被覆盖了。换句话说,文件:File2.sh、File3.R 和 File4.R 具有 File1.bash 的内容。

谁能帮我解决这个问题?

非常感谢

【问题讨论】:

【参考方案1】:

这里的问题是通配符*被目录中的每个文件替换,包括File2.sh、File3.R等。因此,在循环期间的某一时刻,$i 将是“File2.sh”,您将执行命令cp File1.bash File2.sh,这将覆盖 File2.sh(其他文件也会出现同样的问题)。

您应该将通配符替换为仅列出目录的命令,例如ls -d */

例如:

for i in $(ls -d */)
do
    cp  File1.bash $i      
    cp  File2.sh $i         
    cp  File3.R $i        
    cp  File4.R $i 
done

另外,请注意 cp 可以将多个参数作为源,所以 cp File1.bash File2.sh File3.R File4.R $i 应该做你想做的事。它也不太容易出错,因为最后一个参数应该是一个目录,所以如果 $i 是一个常规文件,cp 会出错。

【讨论】:

不客气。另请参阅我关于 cp 的编辑接受几个参数和 pabouk 的回答,其中包含非常有用的建议。【参考方案2】:

for循环遍历当前目录中的所有文件和目录(名称以点开头的除外),包括文件File1.bashFile2.sFile3.RFile4.R,所以迟早他们会出现在cp 命令的目标位置并被覆盖。

解决问题的方法有多种:

仅展开目录

for i in */ ; do
    cp  File1.bash File2.sh File3.R File4.R "$i"
done

测试目标是否为目录

for i in * ; do
    if test -d "$i" ; then
        cp  File1.bash File2.sh File3.R File4.R "$i"
    fi
done

与第一个答案相比,此代码不需要调用额外的外部命令 (ls),无论如何解析 ls 的输出也不是一个好主意:)(它可能包含一些意外内容。)

将源文件移动到其他位置

例如,将文件移动到名为 .template 的目录(点很重要)或当前目录之外的目录 (../template):

mv File1.bash File2.sh File3.R  File4.R .template

更改的脚本(不会循环通过隐藏的.template):

source=.template
for i in * ; do
    cp  "$source/File1.bash" "$i"
    cp  "$source/File2.sh" "$i"
    cp  "$source/File3.R" "$i"
    cp  "$source/File4.R" "$i"
done

使用双引号

在双引号之间展开变量时,最好将字符串括起来。然后脚本也将正确处理包含空格换行符等的字符串。

【讨论】:

哈哈,原来我忘了最直接的解决办法——第一个脚本:)

以上是关于在 cp 循环期间覆盖的文件的主要内容,如果未能解决你的问题,请参考以下文章

如何在while循环期间运行“文件存在”函数(expect/tcl)作为条件?

for循环求和中的for循环正在覆盖数据值python

时间循环 - 将矢量数据存储在文件中而不覆盖

为啥我的 for 循环覆盖而不是追加?

为什么bash动态变量和字符串串联会扰乱/覆盖我的循环输出?

在循环期间更新进度条