AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 1541429
Accepted
Alan
Alan
Asked: 2025-02-14 20:49:23 +0800 CST2025-02-14 20:49:23 +0800 CST 2025-02-14 20:49:23 +0800 CST

如何在 Bash 脚本的一行上连接两个命令输出?

  • 772

如果有所不同,则运行 Ubuntu 24.04 LTS。

我试图在 bash 脚本中将两个命令的结果(输出到 stdout)输出到一行上,但似乎无法让它工作——我在两行上得到了两个输出。

我尝试过的命令(以及其许多变体)是:

ssh [email protected] -- 'echo -n "VMName : " && lsblk | grep -i disk' && 'echo -n "  Hypervisor = HypervisorHostName"'

输出结果分为两行,如下所示:

VMName :vda 254:0 0 20G 0 磁盘

虚拟机管理程序 = HypervisorHostName

而我想得到:

VMName :vda 254:0 0 20G 0 磁盘 Hypervisor = HypervisorHostName

我觉得这很简单。我是不是忽略了显而易见的东西?

谢谢,

艾伦。

bash
  • 5 5 个回答
  • 514 Views

5 个回答

  • Voted
  1. Best Answer
    Raffa
    2025-02-15T00:11:29+08:002025-02-15T00:11:29+08:00

    请注意,命令行中最后一个&&ie之后的部分将在会话关闭后echo -n " Hypervisor = HypervisorHostName"在您本地的计算机上执行,而不会在远程计算机上或会话期间执行...在您的情况下,仅传递第一组单引号之间的命令。sshsshsshssh'...'

    也就是说,你似乎主要处理字符串,你显然可以完全控制它们的打印方式,除了决定的lsblk | grep -i disk位之外grep......我在想为什么不使用命令替换语法将其转换为字符串,然后使用 shell 的内置函数及其字符串说明$(...)符将整个内容格式化为一个字符串,如下所示:printf%s

    ssh [email protected] -- 'printf "%s\n" "VMName : $(lsblk | grep -i disk) Hypervisor = HypervisorHostName"' 
    
    • 5
  2. steeldriver
    2025-02-14T23:21:43+08:002025-02-14T23:21:43+08:00

    一般来说,您可以通过管道将标准输出连接到paste -s行对。

    但是在这种情况下我建议使用awk而不是以便grep您可以直接打印所需的格式化输出,例如:

    $ lsblk | gawk -v IGNORECASE=1 '/disk/{print "VMNAME : " $0 " Hypervisor = HypervisorHostName"}'
    VMNAME : sda      8:0    0    36G  0 disk  Hypervisor = HypervisorHostName
    

    如果您确实不需要不区分大小写的匹配,则可以省略IGNORECASE=1并使用任何 POSIX 。awk

    或者,你可以全力以赴,使用lsblk命令的 JSON 输出,选择磁盘并使用打印所需的字符串jq- 这将防止在输出中的其他地方出现字符串“disk”的错误匹配 - 例如

    $ lsblk -J | jq -r '.blockdevices[] | select(.type == "disk") | 
        "VMNAME : \(.name) \(.size) Hypervisor = HypervisorHostName"'
    VMNAME : sda    36G     Hypervisor = HypervisorHostName
    

    或者

    $ lsblk -J | jq -r '.blockdevices[] | select(.type == "disk") | 
        ["VMNAME : ", .name, .size, "Hypervisor = HypervisorHostName"] | @tsv'
    VMNAME :        sda     36G     Hypervisor = HypervisorHostName
    

    (我省略了一些."maj:min"可能不感兴趣的字段)。

    • 4
  3. Hannu
    2025-02-15T00:21:12+08:002025-02-15T00:21:12+08:00

    以下几件简单的事情可能会让你行动起来:

    # 内联评论,就像这样
    
    # 第一个 echo 有不打印换行符的选项
    $ echo -n“a”&& echo“b”
    AB
    
    # $(命令) 运行命令并将其输出保留为文本
    $ echo "$(echo a && echo b)"
    一个
    b
    
    # 与上面相同,但是;请注意管道仅用于 echo b
    $ echo "$(echo a && echo b | tr -d '\n' )"
    一个
    b
    
    # 同样在这里...
    $ echo "$(echo a && echo b | tr '\n' ' ' )"
    一个
    b
    
    # 额外的括号“连接”了命令(它们在子 shell 中运行),
    # 所以它们都将输出发送到管道中
    $ echo "$( (echo a && echo b) | tr '\n' ' ' )"
    AB
    
    # 使用 tr 的 -d 选项删除换行符
    $ echo "$( ( echo a && echo b ) | tr -d '\n' )"
    AB
    
    # 稍微简化
    $ ( 回显 a && 回显 b ) | tr '\n' ' '
    AB $
    
    

    www.tldp.org有 PDF 版的“Bash 指南”——我建议浏览一下,也许能学到一两个窍门。
    这样你就知道有什么了,然后可以通过搜索查找。

    • 2
  4. robert rozee
    2025-02-14T21:23:54+08:002025-02-14T21:23:54+08:00

    请尝试一下:

    user@user-DH61BE:~$ whoami
    user
    user@user-DH61BE:~$ hostname
    user-DH61BE
    user@user-DH61BE:~$ { whoami & hostname; } | sed 'N;s/\n/ /'
    user-DH61BE user
    user@user-DH61BE:~$
    user@user-DH61BE:~$ { echo 'second-string' & echo 'first-string'; } | sed 'N;s/\n/ /'
    first-string second-string
    user@user-DH61BE:~$ 
    

    如果这实现了您的要求,请告诉我们:-)

    附录:正如terdon指出的那样,我意外地使用了 & 而不是 &&。作为额外的奖励,&& 可以正确获取从左到右的顺序:

    user@user-DH61BE:~$ { echo 'first-string' && echo 'second-string'; } | sed 'N;s/\n/ /'
    first-string second-string
    user@user-DH61BE:~$ 
    
    • -1
  5. user3353751
    2025-02-17T00:26:04+08:002025-02-17T00:26:04+08:00

    这是被诅咒的,但它一直有效,直到它失效为止,并且在后一种情况下充当其自身的解释:

    sed 's,\x0a,,g'<<<$(echo `lnout && lnout2`)
    

    更棒的是,作为一个清晰可见的权宜之计,它实际上适用于以下语法:

    sed 's#\x0a##g'<<<$(echo `lnout && lnout2`)
    

    如果不以 ### 开头,则行的开头还不够明确。

    • -1

相关问题

  • 同时复制到两个位置

  • 如何在 shell 脚本中创建选择菜单?

  • 从 bash 迁移到 zsh [关闭]

  • bashrc 还是 bash_profile?

  • 备份 bash 脚本未压缩其 tarball

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve