我正在尝试在for
循环中使用rsync
或cp
来复制与存储在.txt
文件中新行上的 200 个名称列表匹配的文件,这些名称与具有.pdbqt
扩展名的文件名匹配,这些文件名位于具有一个父文件夹的一系列子目录中。.txt
文件如下所示:
file01
file02
file08
file75
file45
...
我尝试将 rsync 与以下命令一起使用:
rsync -a /home/ubuntu/Project/files/pdbqt/*/*.pdbqt
--files-from=/home/ubuntu/Project/working/output.txt
/home/ubuntu/Project/files/top/
当我运行 rsync 命令时,我收到:
rsync error: syntax or usage error (code 1) at options.c(2346) [client=3.1.2]
我编写了一个 bash 脚本,如下所示,试图让它工作:
#!/bin/bash
for i in "$(cat /home/ubuntu/Project/working/output.txt | tr 'n' '')"; do
cp /home/ubuntu/Project/files/pdbqt/*/"$i".pdbqt /home/ubuntu/Project/files/top/;
done
我知道cat
不是一个很好的命令,但我无法找到它的替代解决方案,因为我仍然不熟悉使用 bash。运行时出现以下错误:
tr: when not truncating set1, string2 must be non-empty
cp: cannot stat '/home/ubuntu/Project/files/pdbqt/*/.pdbqt': No such file or directory
我假设 tr 错误是由于 tr 错误而抛出的cp
错误,但我不确定如何摆脱从新行分隔列表中读取的n
。
预期的结果是,从包含 12000 个.pdbqt
文件的子/pdbqt/
目录中,输出.txt列表中的 200 个文件将从这些子目录中复制到/top/
目录中。
当你的数据已经在shell变量中时,for
循环是很好的。 从文件中读入数据时,while ... read
循环效果更好。 在您的情况下,请尝试:
while IFS= read -r file; do cp -i -- /home/ubuntu/Project/files/pdbqt/*/"$file".pdbqt /home/ubuntu/Project/files/top/; done </home/ubuntu/Project/working/output.txt
或者,如果您发现多行版本更具可读性:
while IFS= read -r file
do
cp -i -- /home/ubuntu/Project/files/pdbqt/*/"$file".pdbqt /home/ubuntu/Project/files/top/
done </home/ubuntu/Project/working/output.txt
工作原理
while IFS= read -r file; do
这将启动一次读取一行的
while
循环。IFS=
告诉 bash 不要截断行中的空格,-r
告诉read
不要破坏反斜杠。 该行存储在名为file
的 shell 变量中。cp -i -- /home/ubuntu/Project/files/pdbqt/*/"$file".pdbqt /home/ubuntu/Project/files/top/
这将复制文件。
-i
告诉cp
在覆盖现有文件之前询问。done </home/ubuntu/Project/working/output.txt
这标志着
while
循环的结束,并告诉 shell 从/home/ubuntu/Project/working/output.txt
获取循环的输入
Project/files/pdbqt/*
或文件中的目录*.pdbqt
名称中是否有破折号 (-
) ?
错误显示 rsync 源代码中的行options.c
"Your options have been rejected by the server.n"
这让我认为它将 glob 中的 inode(文件/目录)解释为 rsync 选项。
for i in $( < /home/ubuntu/Project/working/output.txt LC_CTYPE=C tr 'n' ' ' )
do
cp /home/ubuntu/Project/files/pdbqt/*/"${i}.pdbqt" /home/ubuntu/Project/files/top/
done
我认为你的猫 tr 缺少一个空格
cat /home/ubuntu/Project/working/output.txt | tr 'n' ' '
John1024 对while
和read
的使用比我的要好。
你的想法是正确的,思考rsync
.rsync
提供了选项--files-from="yourfile"
,该选项将textfile
中的所有文件(相对于您接下来指定的基目录)rsync
到目标(host:/dest/path
或本地仅/dest/path
)
您需要指定--no-R
以告诉rsync
不要使用相对文件名,因为--files-from=
将基路径作为下一个参数。例如,要将文本文件中的所有文件传输到指定文件的位置位于当前目录中的某个远程主机,可以使用:
rsync -uai --no-R --files-from="textfile" ./ host:/dest/path
命令实质上指定您读取要从textfile
传输的名称,文件将在./
(当前目录)下找到,您将文件传输到您指定的host
上的host:/dest/path
。您可以看到 man 1 rsync 了解完整详细信息。