我想在 ftp 目录上递归地使用 wget,如下所示:
ftp://ftp.ensembl.org/pub/current_fasta/
其中包含另外 2 个目录级别,第一个目录包含物种名称,第二个目录包含名称dna
,如下所示:
ftp://ftp.ensembl.org/pub/current_fasta/species_name/dna/
例如,其中之一具有species_name homo_sapiens
:
ftp://ftp.ensembl.org/pub/current_fasta/homo_sapiens/dna/
在每个./dna/
目录中,我只想下载名称包含单词的文件toplevel
,而不下载包含单词的文件_rm.toplevel
。
最后,我想要一个 wget 递归命令来下载这些目录中的所有文件,每个文件作为名称为 的输出文件species_name.fa.gz
,其中 是species_name
父目录的名称,就在 之前dna
。
有任何想法吗?
答案1
您可以告诉 wget 根据通配符模式包含或排除文件和目录。未经测试:
wget -R \
-X '/*/?*dna,/*/pep' \
-A '*toplevel*' -R '*_rm.toplevel*' \
ftp://ftp.ensembl.org/pub/current_fasta/
对于 FTP,wget 并不是复杂检索的最佳工具。 Wget 知道如何跟踪网页中的链接,但这与 FTP 无关。我建议将 FTP 站点安装为目录AVFS,卷曲FTPFS或其他一些保险丝文件系统,并使用cp
或rsync
.使用 AVFS:
mountavfs
ls ~/.avfs/\#ftp:ftp.ensembl.org/pub/current_fasta/homo_sapiens
使用 CurlFtpFS:
mkdir ~/current_fasta
curlftpfs ftp://ftp.ensembl.org/pub/current_fasta/ ~/current_fasta
ls ~/current_fasta/homo_sapiens
要在任何 shell 中复制文件:
for x in ~/.avfs/\#ftp:ftp.ensembl.org/pub/current_fasta/*/dna/*toplevel*; do
case $x in *_rm.toplevel*) continue;; esac
species=${x%/dna/*}; species=${species##*/}
cp -p "$x" "$species.fa.gz"
done
或者在 zsh 中:
autoload zmv
zmv -C '~/.avfs/\#ftp:ftp.ensembl.org/pub/current_fasta/(*)/dna/*toplevel*~*_rm.toplevel*' '$1.fa.gz'
答案2
如果可以使用lftp
:
echo 'mirror --no-empty-dirs -I *toplevel* -X *_rm.toplevel* . .' |
lftp ftp://ftp.ensembl.org/pub/current_fasta/
for folder in *; do
mv $folder/dna/*toplevel* $folder.fa.gz
rm -r "$folder"
done