微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Linux 字符串操作从一个参数生成两个参数

如何解决Linux 字符串操作从一个参数生成两个参数

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

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

解决方法

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

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 只抓取一个参数。您可以将 images: 粘在 sed 中,然后使用您的 sed 保持空间改组传递它:

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

但无论如何我都看不到 xargs 的价值。

,

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。