从“conda list”输出安装所有内容
Install everything from a `conda list` output
我有一个文件,conda_env.txt,保存了 conda list
的标准输出。它具有以下结构。
conda_env.txt
# packages in environment at /scratch/hello/anaconda3:
#
# Name Version Build Channel
_ipyw_jlab_nb_ext_conf 0.1.0 py37_0
absl-py 0.7.1 pypi_0 pypi
alabaster 0.7.12 py37_0
anaconda-client 1.7.2 py37_0
anaconda-navigator 1.9.7 py37_0
anaconda-project 0.8.2 py37_0
annoy 1.14.0 pypi_0 pypi
我想要conda install
此文件中列出的所有软件包,并指定版本。
我的想法是for循环遍历所有行(从第4行开始),从第一个和第二个字段中获取值,并将它们保存到PACKAGE
和VERSION
中,然后安装通过调用 conda install $PACKAGE=$VERSION
(例如,conda install pandas=0.20.3
我想编写一个 shell 脚本来执行此操作。我写了一个演示文件只是为了读取第 i 行和它的第二个字段:
#!/bin/bash
LINES=$(wc -l < conda_env.txt)
for i in {4...10}
do
awk -F '|' 'NR==${i}{print }' conda_env.txt
done
它给我错误:awk: bailing out at source line 1
。
知道这里出了什么问题以及如何正确处理吗?
请您尝试以下操作:
#!/bin/bash
while read -r package version _; do
[[ $package = "#"* ]] && continue # skip the comment lines
# remove "echo" if the output looks good
echo conda install "$package=$version"
done < "conda_env.txt"
输出:
conda install _ipyw_jlab_nb_ext_conf=0.1.0
conda install absl-py=0.7.1
conda install alabaster=0.7.12
conda install anaconda-client=1.7.2
conda install anaconda-navigator=1.9.7
conda install anaconda-project=0.8.2
conda install annoy=1.14.0
如果输出行符合您的预期,则删除 echo
并执行脚本。
转换为 YAML
我写了 an AWK script 来将 conda list
的输出转换为与 conda env create -f env.yaml
兼容的 YAML。这应该比一系列 conda install
调用更受青睐,后者导致 运行 对每个单独的包进行求解。
AWK 脚本
list_to_yaml.awk
#!/usr/bin/env awk -f
#' Author: Mervin Fansler
#' GitHub: @mfansler
#' License: MIT
#' Usage
#' $ conda list | awk -f list_to_yaml.awk
{
# skip header
if ( ~ /^#/) { next }
if ( ~ /pypi/) { # pypi packages
pip=1;
pypi[i++]=" - ""=="" ";
} else { # conda packages
if ( ~ /pip/) {
pip=1;
} else {
conda[j++]=" - ""="" ";
}
# include channels
if (!seen[]) {
if (length() == 0) {
channels[k++]=" - defaults ";
} else {
channels[k++]=" - "" ";
}
++seen[];
}
}
}
END {
# emit channel info
print "channels: ";
for (k in channels) print channels[k];
# emit conda pkg info
print "dependencies: ";
for (j in conda) print conda[j];
# emit PyPI pkg info
if (pip) print " - pip ";
if (length(pypi) > 0) {
print " - pip: ";
for (i in pypi) print pypi[i];
}
}
用法
假设我们有一个环境foo,有人为(foo_list.txt
)转储了一个conda list
,我们可以创建一个相应的YAML文件(foo.yaml
), 然后用它来生成一个新的环境, bar.
# dump a `conda list` for environment `foo`
conda list -n foo > foo_list.txt
# convert to YAML
awk -f list_to_yaml.awk foo_list.txt > foo.yaml
# edit the foo.yaml channels section manually!
# usually should be `conda-forge` at the top, `defaults` at the bottom
# emacs foo.yaml
# create the new environment
conda env create -n bar -f foo.yaml
或者,如果您只是想测试一下,管道也可以:
conda list -n foo | awk -f list_to_yaml.awk
优势
- 自动处理来自 PyPI 的包
- 处理频道(排序;顺序可能不是最佳的)
- 为安装创建单个文件
- 不会重复调用
conda install
,这会导致大量不必要的求解
我有一个文件,conda_env.txt,保存了 conda list
的标准输出。它具有以下结构。
conda_env.txt
# packages in environment at /scratch/hello/anaconda3:
#
# Name Version Build Channel
_ipyw_jlab_nb_ext_conf 0.1.0 py37_0
absl-py 0.7.1 pypi_0 pypi
alabaster 0.7.12 py37_0
anaconda-client 1.7.2 py37_0
anaconda-navigator 1.9.7 py37_0
anaconda-project 0.8.2 py37_0
annoy 1.14.0 pypi_0 pypi
我想要conda install
此文件中列出的所有软件包,并指定版本。
我的想法是for循环遍历所有行(从第4行开始),从第一个和第二个字段中获取值,并将它们保存到PACKAGE
和VERSION
中,然后安装通过调用 conda install $PACKAGE=$VERSION
(例如,conda install pandas=0.20.3
我想编写一个 shell 脚本来执行此操作。我写了一个演示文件只是为了读取第 i 行和它的第二个字段:
#!/bin/bash
LINES=$(wc -l < conda_env.txt)
for i in {4...10}
do
awk -F '|' 'NR==${i}{print }' conda_env.txt
done
它给我错误:awk: bailing out at source line 1
。
知道这里出了什么问题以及如何正确处理吗?
请您尝试以下操作:
#!/bin/bash
while read -r package version _; do
[[ $package = "#"* ]] && continue # skip the comment lines
# remove "echo" if the output looks good
echo conda install "$package=$version"
done < "conda_env.txt"
输出:
conda install _ipyw_jlab_nb_ext_conf=0.1.0
conda install absl-py=0.7.1
conda install alabaster=0.7.12
conda install anaconda-client=1.7.2
conda install anaconda-navigator=1.9.7
conda install anaconda-project=0.8.2
conda install annoy=1.14.0
如果输出行符合您的预期,则删除 echo
并执行脚本。
转换为 YAML
我写了 an AWK script 来将 conda list
的输出转换为与 conda env create -f env.yaml
兼容的 YAML。这应该比一系列 conda install
调用更受青睐,后者导致 运行 对每个单独的包进行求解。
AWK 脚本
list_to_yaml.awk
#!/usr/bin/env awk -f
#' Author: Mervin Fansler
#' GitHub: @mfansler
#' License: MIT
#' Usage
#' $ conda list | awk -f list_to_yaml.awk
{
# skip header
if ( ~ /^#/) { next }
if ( ~ /pypi/) { # pypi packages
pip=1;
pypi[i++]=" - ""=="" ";
} else { # conda packages
if ( ~ /pip/) {
pip=1;
} else {
conda[j++]=" - ""="" ";
}
# include channels
if (!seen[]) {
if (length() == 0) {
channels[k++]=" - defaults ";
} else {
channels[k++]=" - "" ";
}
++seen[];
}
}
}
END {
# emit channel info
print "channels: ";
for (k in channels) print channels[k];
# emit conda pkg info
print "dependencies: ";
for (j in conda) print conda[j];
# emit PyPI pkg info
if (pip) print " - pip ";
if (length(pypi) > 0) {
print " - pip: ";
for (i in pypi) print pypi[i];
}
}
用法
假设我们有一个环境foo,有人为(foo_list.txt
)转储了一个conda list
,我们可以创建一个相应的YAML文件(foo.yaml
), 然后用它来生成一个新的环境, bar.
# dump a `conda list` for environment `foo`
conda list -n foo > foo_list.txt
# convert to YAML
awk -f list_to_yaml.awk foo_list.txt > foo.yaml
# edit the foo.yaml channels section manually!
# usually should be `conda-forge` at the top, `defaults` at the bottom
# emacs foo.yaml
# create the new environment
conda env create -n bar -f foo.yaml
或者,如果您只是想测试一下,管道也可以:
conda list -n foo | awk -f list_to_yaml.awk
优势
- 自动处理来自 PyPI 的包
- 处理频道(排序;顺序可能不是最佳的)
- 为安装创建单个文件
- 不会重复调用
conda install
,这会导致大量不必要的求解