我正在寻找一些方向 - 因为它有点有效,但没有。
我有一个本地硬盘,想将所有 .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
将在两个单独的行上打印"foo
and 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