rsync - 使用 shell 脚本将每个 JPG/jpg 文件从一个硬盘驱动器移动到单个目录

rsync - 使用 shell 脚本将每个 JPG/jpg 文件从一个硬盘驱动器移动到单个目录

我正在寻找一些方向 - 因为它有点有效,但没有。

我有一个本地硬盘,想将所有 .JPG 和 .jpg 文件复制到单身的另一个本地硬盘上的目录。

使用rsync - 我的想法:(源硬盘驱动器是Windows机器 - 文件名有空格)
- 获取源硬盘驱动器上所有目录的列表并放入文本文件
- 编辑目录列表文本文件以在周围添加引号every dir
-- 使用 shell 脚本循环在文本文件的每一行上运行 rsync



如果我在命令行使用 rysnc 并单独复制目录,它就可以工作。

rsync -r --include '*.jpg' --include '*.JPG' --exclude '*' --prune-empty-dirs /"media"/"tfrd"/"Disk06_01_M"/"Disk02_01_X"/"x_images and camera"/"vernon pics_other"/"office_PBWT4_YBP6D-7wmff_bpwg4_2vgby"/"office pro disk 2"/"BCM"/"Program Files"/"Microsoft Small Business"/"Business Contact Manager"/"SDKComponents"/"PPCRL"/ /home/tfrd/Desktop/filesync/rsync/dir2/  

使用 Shell 脚本 - 它不起作用 - 问题在于 dir 变量和正斜杠或空格 - 最重要的是 - 它似乎尝试在最后一个目录之前进行解析

我尝试了 $IFS 的变化 - 因为我认为这就是解析问题所在。


我的脚本:

#!/bin/bash
file="/home/tfrd/Desktop/filesync/rsync/test_data_01.txt"

while IFS=$'\n' read -r line
#while IFS= read -r line
#while read line
do

#try 01
#rsync  --include '*.jpg' --include '*.JPG' --exclude '*/*/.' $line /home/rsync/dir2

#try 02
#rsync  --include '*.jpg' --include '*.JPG' --exclude '/*/' $line /home/rsync/dir2

#try 03
#rsync  --include '*.jpg' --include '*.JPG' --exclude '*/*/' $line /home/rsync/dir2

#try 04
rsync --protect-args --include '*.jpg' --include '*.JPG' --exclude '*/*/.' --prune-empty-dirs $line /home/rsync/dir2

done <"$file"



我的测试数据:(txt文件中只有2行)

/"media"/"tfrd"/"Disk06_01_M"/"Disk02_01_X"/"x_images and camera"/"vernon pics_other"/"office_PBWT4_YBP6D-7wmff_bpwg4_2vgby"/"office pro disk 2"/"BCM"/"Program Files"/"Microsoft Small Business"/"Business Contact Manager"/"SDKComponents"/"PPCRL"/
/"media"/"tfrd"/"Disk06_01_M"/"Disk02_01_X"/"x_images and camera"/"vernon pics_other"/"office_PBWT4_YBP6D-7wmff_bpwg4_2vgby"/"office pro disk 2"/"SBA"/"program files"/"Microsoft Small Business"/"Office Accounting 2008"/"SDKComponents"/"PPCRL"/



结果:(清理后可读)

tfrd@Beagle-Ubuntu:~/Desktop/filesync/rsync$ clear


tfrd@Beagle-Ubuntu:~/Desktop/filesync/rsync$ ./script.sh 
/media/tfrd/Disk06_01_M/Disk02_01_X/x_images and camera/vernon pics_other/office_PBWT4_YBP6D-7wmff_bpwg4_2vgby/office pro disk 2/BCM/Program Files/Microsoft Small Business/Business Contact Manager/SDKComponents/PPCRL

rsync: link_stat "/media/tfrd/Disk06_01_M/Disk02_01_X/x_images" failed: No such file or directory (2)
rsync: link_stat "/home/tfrd/Desktop/filesync/rsync/and" failed: No such file or directory (2)
rsync: change_dir "/home/tfrd/Desktop/filesync/rsync//camera" failed: No such file or directory (2)
rsync: change_dir "/home/tfrd/Desktop/filesync/rsync//pics_other/office_PBWT4_YBP6D-7wmff_bpwg4_2vgby" failed: No such file or directory (2)
rsync: link_stat "/home/tfrd/Desktop/filesync/rsync/pro" failed: No such file or directory (2)
rsync: link_stat "/home/tfrd/Desktop/filesync/rsync/disk" failed: No such file or directory (2)
rsync: change_dir "/home/tfrd/Desktop/filesync/rsync//2/BCM" failed: No such file or directory (2)
rsync: change_dir "/home/tfrd/Desktop/filesync/rsync//Files" failed: No such file or directory (2)
rsync: link_stat "/home/tfrd/Desktop/filesync/rsync/Small" failed: No such file or directory (2)
rsync: change_dir "/home/tfrd/Desktop/filesync/rsync//Business" failed: No such file or directory (2)
rsync: link_stat "/home/tfrd/Desktop/filesync/rsync/Contact" failed: No such file or directory (2)
rsync: change_dir "/home/tfrd/Desktop/filesync/rsync//Manager/SDKComponents" failed: No such file or directory (2)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1183) [sender=3.1.0]


/media/tfrd/Disk06_01_M/Disk02_01_X/x_images and camera/vernon pics_other/office_PBWT4_YBP6D-7wmff_bpwg4_2vgby/office pro disk 2/SBA/program files/Microsoft Small Business/Office Accounting 2008/SDKComponents/PPCRL

rsync: link_stat "/media/tfrd/Disk06_01_M/Disk02_01_X/x_images" failed: No such file or directory (2)
rsync: link_stat "/home/tfrd/Desktop/filesync/rsync/and" failed: No such file or directory (2)
rsync: change_dir "/home/tfrd/Desktop/filesync/rsync//camera" failed: No such file or directory (2)
rsync: change_dir "/home/tfrd/Desktop/filesync/rsync//pics_other/office_PBWT4_YBP6D-7wmff_bpwg4_2vgby" failed: No such file or directory (2)
rsync: link_stat "/home/tfrd/Desktop/filesync/rsync/pro" failed: No such file or directory (2)
rsync: link_stat "/home/tfrd/Desktop/filesync/rsync/disk" failed: No such file or directory (2)
rsync: change_dir "/home/tfrd/Desktop/filesync/rsync//2/SBA" failed: No such file or directory (2)
rsync: change_dir "/home/tfrd/Desktop/filesync/rsync//files" failed: No such file or directory (2)
rsync: link_stat "/home/tfrd/Desktop/filesync/rsync/Small" failed: No such file or directory (2)
rsync: change_dir "/home/tfrd/Desktop/filesync/rsync//Business" failed: No such file or directory (2)
rsync: link_stat "/home/tfrd/Desktop/filesync/rsync/Accounting" failed: No such file or directory (2)
rsync: change_dir "/home/tfrd/Desktop/filesync/rsync//2008/SDKComponents" failed: No such file or directory (2)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1183) [sender=3.1.0]

答案1

您不需要引用每个路径元素。

在包含路径列表的文本文件中,最好不要有任何引号,而只使用文件名:

/media/tfrd/Disk06_01_M/Disk02_01_X/x_images and camera/vernon pics_other/office_PBWT4_YBP6D-7wmff_bpwg4_2vgby/office pro disk 2/BCM/Program Files/Microsoft Small Business/Business Contact Manager/SDKComponents/PPCRL/
/media/tfrd/Disk06_01_M/Disk02_01_X/x_images and camera/vernon pics_other/office_PBWT4_YBP6D-7wmff_bpwg4_2vgby/office pro disk 2/SBA/program files/Microsoft Small Business/Office Accounting 2008/SDKComponents/PPCRL/

然后像这样编写脚本:

#!/bin/bash
file="/home/tfrd/Desktop/filesync/rsync/test_data_01.txt"

while IFS=$'\n' read -r line
do
    rsync --protect-args --include '*.jpg' --include '*.JPG' --exclude '*/*/.' --prune-empty-dirs "$line" /home/rsync/dir2
done < "$file"

就是这样。请注意,当用作 的路径参数时,$line被括在 中。这将确保正确处理任何嵌入的空格和其他特殊字符。内部的整个内容被视为单个值,这就是它起作用的原因。"..."rsync"..."

答案2

你有过

while IFS=$'\n' read -r line ; do
    rsync ... $line /some/target/dir
done < inputfile

包含inputfile这样的行:

/"media"/"tfrd"/"blah blah"/"yet another dir"/"foo"

您在某种程度上处于正确的轨道上,因为使用引号和/或设置IFS将有助于防止分词。然而,也存在一些问题。

首先,变量内的引号根本不重要,如果变量在扩展后被拆分,那么它就被拆分了。例如var='"foo bar"'; printf "%s\n" $var将在两个单独的行上打印"fooand bar"(它们作为printf两个参数)。相反,您需要在扩展变量时引用该变量,例如var='foo bar'; printf "%s\n" "$var"

其次,在控制字拆分的内容时IFS,您仅在 的持续时间内将其设置为换行符read,而不是脚本的其余部分。这可以让您免于read进行任何拆分,但不能避免在未加引号的扩展之后进行拆分。在脚本开头进行设置IFS=$'\n';也会使其对扩展有效,但最好还是引用(因为它也避免了通配符)。

由于read使用换行符作为停止读取的分隔符,因此我们不妨给它一个空的IFS,而不是带有换行符的。

所以,你可能想要

while IFS= read -r line ; do
    rsync ... "$line" /some/target/dir
done < inputfile

输入文件不包含引号

/media/tfrd/blah blah/yet another dir/foo

相关内容