【问题标题】:Using RSync to copy a sequential range of files使用 RSync 复制一系列文件
【发布时间】:2023-03-20 20:11:01
【问题描述】:

对不起,如果这没有意义,但我会尽力提供所有需要的信息!

我想使用 rsync 将一系列按顺序编号的文件从一个文件夹复制到另一个文件夹。

我正在归档一个 DCDM(它是电影的东西),它包含大约 600,000 个单独编号的连续 .tif 图像文件(约 10mb 个)。

我需要将其分解以正确归档到 LTO6 磁带上。我想使用 rsync 来准备文件夹,这样我的简单 bash .sh 文件就可以自动执行我想要备份到磁带的各种文件夹和文件。

我在运行 rsync 时通常使用的命令是:

sudo rsync -rvhW --progress --size only <src> <dest>

如果需要,我会使用sudo,并且我总是先使用--dry-run 测试结果

我有任何工作(不排除错误)的唯一方法是使用* 通配符。但是,这只适用于具有设置模式的文件(例如,01* 只会从010000 - 019999 范围内移动文件),我必须重复020304 等。

我在互联网上查看过,正在努力寻找一个有效的答案。

这可能是不可能的,并且对于 600,000 个 .tif 文件,我无法为每个文件编写一个排除项!

关于如何(如果有的话)可以做到这一点有什么想法吗?

欧文。

【问题讨论】:

  • 你可以用最简单的通配符*匹配所有文件。如果匹配的文件过多,您需要告诉我们您要排除哪些其他模式,以便我们帮助您缩小匹配范围。
  • @5gon12eder 好的,我是 Linux 新手,所以不确定什么是 globing……就文件而言,它们的命名约定为“legendary_dcdm_3dXXXXXX.tif”(其中X 是一个数字)...我想将 20 个 -50K 文件移动到单独的文件中,这 a) 分解了文件夹的大小,使其适合 LTO6 磁带,并且 b) 如果恢复则更容易随时随地...

标签: linux bash ubuntu rsync


【解决方案1】:

您可以使用pattern matching检查以数字开头的文件名:

for file in [0-9]*; do
    # do something to $file name that starts with digit
done

或者,您可以启用extglob 选项并遍历所有仅包含数字的文件名。这可以消除任何以数字开头但在第一个字符后包含非数字的潜在不需要的文件。

shopt -s extglob
for file in +([0-9]); do
    # do something to $file name that contains only digits
done
  • +([0-9]) 扩展为出现一个或多个数字

更新:

根据您最近评论中的文件名模式:

shopt -s extglob
for file in legendary_dcdm_3d+([0-9]).tif; do
    # do something to $file
done

【讨论】:

  • 您需要为此启用 extglob 选项
  • 知道这个很有用!!!不过,谢谢,当我回复评论时,文件格式为:legendary_dcdm_3dXXXXXX.tif 那么您如何调整它以适应有文本开头的事实?
  • @OwenMorgan 我已更新帖子以匹配您评论中提供的格式的文件名。
  • @JohnB 我很困惑............我使用了你写的代码,添加了rsync -rvhW --progress --size-only $file /000000-050000_test 并且没有移动 tif ......我使用了以下范围 @987654328 @(前导 0 出现在文件名中
【解决方案2】:

Globing 是 shell 将通配符扩展为匹配文件名列表的功能。您已经在问题中使用了它。

对于以下解释,我假设我们在一个包含以下文件的目录中:

$ ls -l
-rw-r----- 1 5gon12eder staff 0 Sep  8 17:26 file.txt
-rw-r----- 1 5gon12eder staff 0 Sep  8 17:26 funny_cat.jpg
-rw-r----- 1 5gon12eder staff 0 Sep  8 17:26 report_2013-1.pdf
-rw-r----- 1 5gon12eder staff 0 Sep  8 17:26 report_2013-2.pdf
-rw-r----- 1 5gon12eder staff 0 Sep  8 17:26 report_2013-3.pdf
-rw-r----- 1 5gon12eder staff 0 Sep  8 17:26 report_2013-4.pdf
-rw-r----- 1 5gon12eder staff 0 Sep  8 17:26 report_2014-1.pdf
-rw-r----- 1 5gon12eder staff 0 Sep  8 17:26 report_2014-2.pdf

最简单的情况是匹配所有文件。以下是穷人的ls

$ echo *
file.txt funny_cat.jpg report_2013-1.pdf report_2013-2.pdf report_2013-3.pdf report_2013-4.pdf report_2014-1.pdf report_2014-2.pdf

如果我们想匹配 2013 年的所有报告,我们可以缩小匹配范围:

$ echo report_2013-*.pdf
report_2013-1.pdf report_2013-2.pdf report_2013-3.pdf report_2013-4.pdf

例如,我们可以省略 .pdf 部分,但我希望尽可能具体。

您已经想出了一个解决方案来使用它来选择一系列编号的文件。例如,我们可以按季度匹配报表:

$ for q in 1 2 3 4; do echo "$q. quater: " report_*-$q.pdf; done
1. quater:  report_2013-1.pdf report_2014-1.pdf
2. quater:  report_2013-2.pdf report_2014-2.pdf
3. quater:  report_2013-3.pdf
4. quater:  report_2013-4.pdf

如果我们懒得输入1 2 3 4,我们可以改用$(seq 4)。这会调用带有参数4 的程序seq 并替换其输出(在本例中为1 2 3 4)。

现在回到你的问题:如果你想要块大小是 10 的幂,你应该能够扩展上面的例子来满足你的需要。

【讨论】:

  • 问题是,当我想要一个范围时会发生什么?使用您的示例:当文件包含 600,000 个 report_2013 文件时,我想列出 report_2013-2 和 report_2013-3 .... 将其从 600,000 个文件扩展到 50,000 个文件的范围
  • legendary_dcdm_3d45*.tif 将扩展为 legendary_dcdm_3d450000.tif ... legendary_dcdm_3d459999.tif。引入一个从 00 到 99 的变量 i,并在循环中使用 legendary_dcdm_3d$i*.tif
  • 使用这个,满足我的需要是一种享受!作为 shell 和 bash 的新手,我不知道循环的最佳方式.....c/c++ 我可以很简单,只是不是 shell/bash。我仍然对第一个建议很感兴趣,但老实说,我还没有完全理解它!
  • 这不是你想要的吗? for i in $(seq -w 0 99); do rm -f MANIFEST.$i; for f in legendary_dcdm_3d$i*.tif; do echo $f &gt;&gt; MANIFST.$i; done; done(它将在当前目录中创建 100 个清单文件,每个文件列出各自范围内的文件。)
  • 我不能再强调这一点了:如果您正在尝试使用 shell(尤其是如果您不确定),请务必不要弄乱您的生产数据。或者你可能会因为一个愚蠢的错字而丢失它!
【解决方案3】:

我知道的老问题,但有人可能会觉得这很有用。上述扩展范围的示例也适用于rsync。例如复制以 a、b 和 c 开头但不是 d 和 e 开头的文件,从 dir /tmp/from_here 复制到 dir /tmp/to_here

$ rsync -avv /tmp/from_here/[a-c]* /tmp/to_here
sending incremental file list
delta-transmission disabled for local transfer or --whole-file
alice/
bob/
cedric/
total: matches=0  hash_hits=0  false_alarms=0 data=0

sent 89 bytes  received 24 bytes  226.00 bytes/sec
total size is 0  speedup is 0.00

【讨论】:

    【解决方案4】:

    如果您要写入 LTO6 磁带,则应考虑在命令中包含“--inplace”。 Inplace 用于写入线性文件系统,例如 LTO

    【讨论】:

      猜你喜欢
      • 2010-10-16
      • 2016-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-30
      • 2020-04-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多