首页 > 解决方案 > Apple终端脚本基于.csv文件名列表复制文件?

问题描述

已经尝试了几个小时来让它工作 - 但我是一个完全的新手(例如今天开始使用终端)并且努力让它工作。

我有一个 csv 文件,它逐行列出文件名。我想找到它们并将它们复制到一个新目录。这些文件列在一个目录中,但每个文件都在其自己的子目录中。

这是我尝试过的,但它没有复制任何东西。但我可以看到它在搜索中循环:

    cat /Users/Will/Downloads/three-new.csv | while IFS=, read col1
do
    find /Volumes/LaCie\ 8tb/BPOTY/2021\ Photos -path $col1 -exec cp {} /Volumes/LaCie\ 8tb/BPOTY/2021\ book \;
done

我也试过这个,但它只是从目录中复制所有文件(剥离子目录)并且没有找到实际的文件名。

cat /Users/Will/Downloads/three-new.csv | while IFS=, read col1
do
    find /Volumes/LaCie\ 8tb/BPOTY/2021\ Photos $col1 -exec cp {} /Volumes/LaCie\ 8tb/BPOTY/2021\ book \;
done

该文件可以在这里看到: https ://www.dropbox.com/s/6uqwzky43r25ors/three.csv?dl=0

已按要求运行命令并输出 CSV:

00000000: 636f 6c31 0d0a 494d 475f 3437 3538 2d64  col1..IMG_4758-d
00000010: 6e2e 6a70 670d 0a43 4f45 5f32 3330 352d  n.jpg..COE_2305-
00000020: 4564 6974 2e74 6966 2e7a 6970 0d0a 5f44  Edit.tif.zip.._D
00000030: 5343 3435 3933 2d68 6972 6573 2d72 6573  SC4593-hires-res
00000040: 6f6c 7574 696f 6e2d 5065 7465 722d 6365  olution-Peter-ce
00000050: 6368 2d54 6865 2d6c 6f6f 6b2e 6a70 67    ch-The-look.jpg

标签: macosterminal

解决方案


由于您在macOS下执行此操作并且该文件具有CRLF结尾,因此首先让我们在Terminal中从三个.csv文件中删除回车

tr -d '\r' < three.csv > new.csv

由于three.csv 文件只有一列,实际上没有逗号,也没有引用条目,这实际上不是一个CSV 文件,可以以更直接的方式处理。为此,请使用以下shell 脚本语法来实现您的目标。

#!/bin/bash

while IFS= read -r line; do
    cd '/path/to/parent_dir' || exit
    find . -type f -iname "$line" -exec cp -av {} '/path/to/destnation_dir' \;
done < '/path/to/new.csv'


备注

  • cd '/path/to/parent_dir' || exit不是绝对必要的,它只是我在许多用例中的首选方法。.后面find可以'/path/to/parent_directory'换成。
  • 带有空格的路径名需要使用反斜杠字符进行转义,或者如果包含variables,则路径需要加引号、单引号或双引号,但不能同时使用两者。作为一般规则,我几乎总是用单引号引用非变量字符串。(昨晚我确实在非变量字符串上使用了双引号,但这是一个错字。)
  • 如果直接在终端中执行,则不需要#!/bin/bash shebang ,如果将其用作独立的shell 脚本,则包括在内。
  • three.csv 文件的最后一行,因此new.csv 文件没有换行符。通过将光标放在第三行的末尾并按回车键来编辑文件,然后保存文件。否则不处理最后一行。
  • 正如 Gordon Davisson 在 OP 的评论中所提到的,引用您的变量并使用ShellCheck检查您的bash shell 脚本代码

推荐阅读