我有一个目录(我们称之为“电影”),其中包含许多文件和文件夹。我在 .csv 文件中有一个很长的文件名列表(大约 4000 个条目),它们引用位于 Movies 目录子文件夹中某处的文件。
如何在 Movies 目录中递归搜索 .csv 中列出的文件并将它们复制到单独的目录(“Sorted_Media”)?
编辑:嗨,我已附上 csv 的示例部分。 .csv 中有两列数据(来自电子表格),由逗号分隔符分隔。第一列文件名是我需要搜索的文件名(即不是 KA* 文件名)。有些文件名确实有空格,因此正如其他人指出的那样,需要考虑这一点。
preservation stocklshots - 16ln916-963.mp4,KA0003773-002.mp4
Preservation Stockshots_ 16LN916-963.mp4,KA0003773-001.mp4
Preservation Stockshots_16LN679-738.mp4,KA0003775-002.mp4
PreservationStockshots_16LN679_738.mp4,KA0003775-001.mp4
Preservation Stockshots_16LN01-52.mp4,KA0003776-002.mp4
Preservation_Stockshots_16LN01_52.mp4,KA0003776-001.mp4
Preservation Stockshots_LN566-LN624.mp4,KA0004507-001.mp4
PreservationStockShots_LN566_LN624.mp4,KA0004507-002.mp4
Preservation Stockshots_LN675-LN705.mp4,KA0004508-001.mp4
PreservationStockshots_LN675_LN705.mp4,KA0004508-002.mp4
Preservation Stockshots_LN706-752.mp4,KA0004509-001.mp4
PreservationStockshots_LN706_LN752.mp4,KA0004509-002.mp4
Preservation Stockshots_LN930-LN972.mp4,KA0004511-001.mp4
PreservationStockShots_LN930_LN972.mp4,KA0004511-002.mp4
Preservation Stockshots_LN1023-LN1059.mp4,KA0004513-001.mp4
PreservationStockShots_LN1023_LN1059.mp4,KA0004513-002.mp4
Preservation Stockshots_LN1152-LN1220.mp4,KA0004515-001.mp4
PreservationStockShots_LN1152_LN1220.mp4,KA0004515-002.mp4
Preservation Stockshots_16LN320-379.mp4,KA0004517-001.mp4
Preservation_Stockshots_16LN320_379.mp4,KA0004517-002.mp4
答案1
while IFS=, read -r file rest
do
find /path/to/movies_dir -name "${file}" -exec cp '{}' /path/to/Sorted_Media/ \;
done < mylist.csv
假设文件名不包含通配符(?
、[
或*
反斜杠)。
答案2
例如,CSV 如下所示:
Spaceballs,/mnt/Movies/Comedy/Spaceballs.avi
Star Wars IV: A New Hope,/mnt/Movies/SciFi/starwars-4.avi
然后你可以做类似的事情:
#!/bin/bash
DEST=/path/to/SortedMedia
for file in $( cut -d, -f 2 /path/to/movielist.csv ); do
cp "$file" $DEST/"${file##*/}"
done
答案3
有了zsh
,你可以这样做:
files=(${(f)"$(cut -d , -f 1 <movies.csv)"})
glob=('$files['{1..$#files}']')
eval "tocopy=(Movies/**/(${(j:|:)glob})(D.))"
print -rl -- $tocopy # to check it's OK
cp -i -- $tocopy Sorted_Media/
解释:
cut -d , -f1 < movies.csv
:检索 csv 的第一列(每行一个文件名)。${(f)"$(cmd)"}
cmd
:分割在线换行的输出($files
现在是一个包含所有文件名的数组)。glob=('$files['{1..$#files}']')
:用字面上的元素创建另一个数组$files[1]
,$files[2]
...${(j:|:)array}
:用 加入数组的元素|
,所以我们基本上是在评估该tocopy=(Movies/**/($files[1]|$files[2]|...|$files[n])(DN.))
命令(其中n
是数组中元素的数量$files
)。**/
:递归通配(搜索任意级别子目录中的文件)。(D.)
:glob 限定符(也在隐藏目录中搜索 (D),仅在常规文件 (.) 中搜索)
或者使用 GNU 工具:
find Movies -type f -print0 |
awk '
!d {f[$1]; next}
$NF in f {
delete f[$NF]
print
}' FS=, file.csv d=1 FS=/ RS='\0' ORS='\0' - |
xargs -r0 cp -vt Sorted_Media/
通过使用delete
,我们确保仅复制第一个实例(如果有多个同名文件)。-i
zsh 解决方案中的功能是让您有机会决定发生冲突时该怎么做。我们不能-i
在这里使用,因为cp
's stdin 不再是终端。
如果您只是想检查它会做什么而不实际执行它,请替换cp
为。echo cp