1

我收到一份操作系统列表,每行一个,例如:

alpine/3.13
alpine/edge
alt/Sisyphus
alt/p9
apertis/v2019.5

我需要将每一行按摩成两个参数以产生:

lxc launch images:alpine/3.13 alpine-3-13
lxc launch images:alpine/edge alpine-edge
lxc launch images:alt/Sisyphus alt-Sisyphus
lxc launch images:alt/p9 alt-p9
lxc launch images:apertis/v2019.5 apertis-v2019-5

然后运行这些命令。请注意,第二个参数已将所有非字母数字切换为连字符。我想出了以下内容:

echo alpine/3.13 | sed 'h;s#[/.]#-#g;x;G;s/\n/ /' | xargs -ti lxc launch images:{}

不幸的是,虽然 xargs 运行的命令看起来是正确的,但 xargs 没有将两个参数传递给 lxc,而是将整个内容作为单个参数传递,因此 lxc 尝试下载名为“alpine/3.13 alpine-3-13”的图像,而不是下载名为 alpine/3.13 的映像并使用它创建一个名为 alpine-3-13 的容器。

有没有办法传递 lxc 两个单独的参数?

示例输出:

# echo alpine/3.13 | sed 'h;s#[/.]#-#g;x;G;s/\n/ /' | xargs -ti lxc launch images:{}
lxc launch images:alpine/3.13 alpine-3-13
Creating the instance
Error: Failed instance creation: The requested image couldn't be found
# lxc launch images:alpine/3.13 alpine-3-13
Creating alpine-3-13
Starting alpine-3-13
<works correctly>

根据来自 KamilCuk 和 markp-fuso 的以下输入完成(工作)最终命令:

lxc image list images: | grep -v cloud | grep -Po '^\| \K[^ ]+(?=.+x86_64.+CONTAINER)' | sed 'h;s#[^[:alnum:]]#-#g;x;G;s/\n/ /;s/^ */images:/' | xargs -n2 lxc launch
4

2 回答 2

0

看起来过于复杂 - 您根本不需要使用容纳空间。为了从模式中记住内容并对其进行改组,请使用反向引用。只是:

echo alpine/3.13 | sed 's#\(.*\)/\(.*\)#lxc launch images:& \1-\2#'

你可以像这样运行:

echo alpine/3.13 | sed 's#\(.*\)/\(.*\)#images:& \1-\2#' | xargs -n2 lxc launch

要不就:

eval "$(echo alpine/3.13 | sed 's#\(.*\)/\(.*\)#lxc launch images:& \1-\2#')"

但无论如何我都会使用正确的代码。

func() {
  arg=${1//\//-}
  lxc launch images:"$1" "$arg"
}
while IFS= read -r line; do
     func "$line"
done <<EOF
alpine/3.13 
EOF

或具有相同功能:

export -f func
echo alpine/3.13 | xargs -d '\n' -n1 bash -c 'func "$@"' _

有没有办法传递 lxc 两个单独的参数?

是的,但xargs必须知道如何处理它。您不能用 xargs 中的某些东西“粘合”两个参数 --i只抓取一个参数。您可以将 in sed 粘合images:然后通过它,使用您的 sed 保持空间洗牌,它是:

echo alpine/3.13 | sed 'h;s#[/.]#-#g;x;G;s/\n/ /;s/^ */images:/' | xargs -t -n2 lxc launch

xargs但无论如何我认为这里没有任何价值。

于 2021-04-27T20:13:51.160 回答
0

OP的示例从echo <operating_system_string>我假设开始意味着输入文件(充满.<operating_systen_string>'s<operating_system_string>

这里的关键点是将使用一个变量来保存当前的<operating_system_string>.

我想知道 OP 是否可以使用参数替换来完成所需的任务,例如:

$ osname='alpine/3.13'
$ echo "${osname//[^[:alnum:]]/-}"     # replace all non-alphanumerics with a '-'
alpine-3-13

所以lxc拨打电话看起来像:

$ echo lxc launch images:"${osname}" "${osname//[^[:alnum:]]/-}"
lxc launch images:alpine/3.13 alpine-3-13

$ lxc launch images:"${osname}" "${osname//[^[:alnum:]]/-}"

在操作系统名称列表中运行...

输入文件:

$ cat oslist
alpine/3.13
alpine/edge
alt/Sisyphus
alt/p9
apertis/v2019.5

通过while循环运行文件:

while read -r osname
do
    echo lxc launch images:"${osname}" "${osname//[^[:alnum:]]/-}"
done < oslist

生成:

lxc launch images:alpine/3.13 alpine-3-13
lxc launch images:alpine/edge alpine-edge
lxc launch images:alt/Sisyphus alt-Sisyphus
lxc launch images:alt/p9 alt-p9
lxc launch images:apertis/v2019.5 apertis-v2019-5

一旦 OP 对结果感到满意,echo就可以将其删除,以便lxc在每次通过循环时调用调用。

于 2021-04-27T21:32:25.670 回答