【问题标题】:Copy all files in folder to another folder prepending a . to the file name and rename it back to original file name将文件夹中的所有文件复制到另一个以 .到文件名并将其重命名回原始文件名
【发布时间】:2020-05-03 03:06:40
【问题描述】:

在搜索并尝试了各种方法后,我无法让它工作。

我需要将大量文件(超过 10 万个文件)复制到另一个文件夹,并在文件名前加上点示例:

/foo/bar/filename1.txt 到 /foo2/bar/.filename1.txt

然后将其重命名为原始名称 /foo2/bar/filename.txt

为什么我需要这样做是因为我有一个应用程序会继续扫描 /foo2/bar 文件夹及其子文件夹,并忽略文件名前面带有点的那些文件,这样它就不会处理那些正在复制一半。这主要是因为 2 个文件夹可以位于 2 个不同的网络驱动器或某些已安装的设备中。

而且我不能简单地使用 mv 或 cp,因为我有一些文件夹有太多文件,它只会抛出参数列表太长的错误,因此我一直在尝试使用 find 命令但无济于事。

尝试不同的命令:

find /foo/bar/ -type f -exec cp -t /foo2/bar {} +

find /foo/bar/ -type f -exec mv {} /foo2/bar/.{} \;

我知道上面的命令不会做我想要的,但那是我已经厌倦了。

感谢任何可以提供帮助的人...

【问题讨论】:

  • 将整个结构复制到/foo3,完成后,将/foo3 重命名为/foo2。这样,扫描/foo2 的应用程序就不会被复制一半的文件所欺骗,直到复制完成并将文件夹重命名为其最终名称。
  • 我认为我不能这样做,因为 /foo2 可能是网络驱动器文件夹,例如 samba 服务器
  • 你不能把文件tar成.mytar.tar.gz然后解压吗?
  • 你的意思是在删除点之前必须复制所有文件?或者每个文件的点可以在该特定文件的副本完成后立即删除?
  • @JL007 作为网络驱动器的问题是什么?您可以在同一网络驱动器中创建/foo3,复制完成后,只需重命名该文件夹即可。重命名将是即时的。

标签: linux bash centos7 file-rename file-copying


【解决方案1】:

使用新名称将所有文件复制到新目录:

for file in *; do   cp "$file" "./files2//.${file}"; done

$ ls -la ./files2/
total 4
 .
 ..
 .1
 .2
 .3

重命名文件:

cd files2
rename . "" .*

输出:

$ ls -la 
total 4
 .
 ..
 1
 2
 3

【讨论】:

  • 我希望它在复制完成后立即重命名回原始文件名,以便可以立即处理,我想我忘了在我的问题中提到它,把它分成几部分是不是我想要的,但无论如何感谢您的帮助!!!
  • 所以把重命名放在循环中——我把它作为一个不同的步骤来向你展示一步一步的细分
【解决方案2】:

假设我们有如下两个目录:

$ ls -a foo*
foo1:
 .   ..   file1   file2   file3  'file 4'

foo2:
.  ..

如果我们执行下一条命令:

$ for file in foo1/* ; do base=$(basename "$file"); cp "foo1/$base" "foo2/.$base"; mv "foo2/.$base" "foo2/$base"; done

我们最终会得到:

$ ls -a foo*
foo1:
.  ..   file1   file2   file3  'file 4'

foo2:
.   ..   file1   file2   file3  'file 4'

我想这就是你想要的。

而且,里面有空格的文件名会被正确处理。

【讨论】:

  • 很好的答案,但如果我敢于挑剔,如果文件名末尾包含换行符,它就会中断。 (谁在乎呢?;)
  • @tshiono:哈哈。我不知道有多少人甚至能够创建一个名称中带有\n 的文件(或带有'/'?)。
  • 哈哈,绝对的:)
  • 天啊!这正是我需要并解决了我的问题。已经测试过了。它是如此简单和优雅!不敢相信我没想到。非常感谢!!!
  • ++ 代表 OP。
【解决方案3】:

你会尝试以下方法:

src="/foo/bar"
dest=/foo2/bar"
while IFS= read -r -d "" f; do
    cp -p -- "$src/$f" "$dest/.$f"
    mv -- "$dest/.$f" "$dest/$f"
done < <(find "$src" -type f -printf "%f\0")

-printf "%f\0"-print0 基本相似,只是它去掉了目录名称。

【讨论】:

  • 我并没有真正尝试过,但还是感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2018-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-25
  • 1970-01-01
  • 2017-02-08
  • 2012-12-01
相关资源
最近更新 更多