如何解决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 举报,一经查实,本站将立刻删除。