在 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.bash
,File2.s
,File3.R
,File4.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)作为条件?