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
    • 最新
    • 标签
主页 / unix / 问题 / 525921
Accepted
CcVHKakalLLOOPPOkKkkKk
CcVHKakalLLOOPPOkKkkKk
Asked: 2019-06-20 13:12:16 +0800 CST2019-06-20 13:12:16 +0800 CST 2019-06-20 13:12:16 +0800 CST

以“相反的顺序”应用大括号扩展

  • 772

例如{a..c}{1..3}扩展为a1 a2 a3 b1 b2 b3 c1 c2 c3.

如果我想打印a1 b1 c1 a2 b2 c2 a3 b3 c3,是否有类似的方法可以做到这一点?最简单的方法是什么?

bash brace-expansion
  • 8 8 个回答
  • 1489 Views

8 个回答

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2019-06-20T13:19:59+08:002019-06-20T13:19:59+08:00

    你可以这样做:

    $ eval echo '{a..c}'{1..3}
    a1 b1 c1 a2 b2 c2 a3 b3 c3
    

    然后告诉外壳评估:

    echo {a..c}1 {a..c}2 {a..c}3
    
    • 31
  2. alsjflalasjf.dev
    2019-06-20T16:31:01+08:002019-06-20T16:31:01+08:00

    对于这种特殊情况,我认为Stéphane Chazelas给出的选项是最好的。

    另一方面,当您扩展更复杂的事物时,此选项无法很好地扩展。因此,您可以通过以下方式实现相同的目的:

    $ printf '%s\0' {a..c}{1..3} | sort -zk 1.2,1.2 | tr '\0' ' '
    

    返回:

    a1 b1 c1 a2 b2 c2 a3 b3 c3
    

    看起来有点乱,但现在,我对命令有很大的控制权,只需在上面的命令中更改两个字符;例如:

    $ echo {a..b}{1..2}{a..b}{1..2}
    

    这将扩展为:

    a1a1 a1a2 a1b1 a1b2 a2a1 a2a2 a2b1 a2b2 b1a1 b1a2 b1b1 b1b2 b2a1 b2a2 b2b1 b2b2
    

    假设我想要1第二个扩展中的所有内容,那么2:

    $ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -zk 1.2,1.2 | tr '\0' ' '
    a1a1 a1a2 a1b1 a1b2 b1a1 b1a2 b1b1 b1b2 a2a1 a2a2 a2b1 a2b2 b2a1 b2a2 b2b1 b2b2
    

    假设我想要a第三个扩展中的所有内容,那么b:

    $ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -zk 1.3,1.3 | tr '\0' ' '
    a1a1 a1a2 a2a1 a2a2 b1a1 b1a2 b2a1 b2a2 a1b1 a1b2 a2b1 a2b2 b1b1 b1b2 b2b1 b2b2
    

    假设我想要1第四次扩展中的所有内容,那么2:

    $ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -zk 1.4,1.4 | tr '\0' ' '
    a1a1 a1b1 a2a1 a2b1 b1a1 b1b1 b2a1 b2b1 a1a2 a1b2 a2a2 a2b2 b1a2 b1b2 b2a2 b2b2
    

    假设我想要1a中间的所有,然后1b,然后2a,然后2b:

    $ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -zk 1.2,1.3 | tr '\0' ' '
    a1a1 a1a2 b1a1 b1a2 a1b1 a1b2 b1b1 b1b2 a2a1 a2a2 b2a1 b2a2 a2b1 a2b2 b2b1 b2b2
    

    您甚至可以很容易地反转上述扩展中的任何顺序,只需r在前面的命令中添加一个即可;例如最后一个:

    $ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -rzk 1.2,1.3 | tr '\0' ' '
    b2b2 b2b1 a2b2 a2b1 b2a2 b2a1 a2a2 a2a1 b1b2 b1b1 a1b2 a1b1 b1a2 b1a1 a1a2 a1a1
    

    Note_1 : 通常,如果这个最终扩展将被用作参数列表,尾随空格不是问题;但是如果你想摆脱它,你可以在上面的任何命令中添加,例如| sed 's/ $//';甚至| sed 's/ $/\n/',将尾随空格更改为newline

    注意_2:在上面的示例中,我使用两个元素的子集(即: {a,b}和{1,2})只是为了简化概念证明:您可以使用任何有限长度的子集,并且相应的命令,将是可比的。

    • 10
  3. user232326
    2019-06-20T14:05:49+08:002019-06-20T14:05:49+08:00

    bash、ksh、zsh

    一种适用于 (bash, ksh, zsh) 的衬里(并非所有 shell 都可以以相反的顺序进行“大括号扩展”):

    $ echo {3..1}{c..a} | rev
    a1 b1 c1 a2 b2 c2 a3 b3 c3
    

    另一种使用方式eval(仍然适用于 bash、ksh、zsh 并且可能更神秘)是:

    $ eval echo '{a..c}'{1..3}
    a1 b1 c1 a2 b2 c2 a3 b3 c3
    

    要了解会发生什么,请替换eval为echo:

    $ echo echo '{a..c}'{1..3}
    echo {a..c}1 {a..c}2 {a..c}3
    

    执行的命令(在 eval 扩展之后)实际上是echo {a..c}1 {a..c}2 {a..c}3. 根据需要/需要扩展。

    所有贝壳

    有几个没有“大括号扩展”的外壳,因此,不可能将其用于“所有外壳”。我们需要一个循环(带有尾随空格):

    $ for i in 1 2 3; do for j in a b c; do printf "%s%s " "$j" "$i"; done; done; echo
    a1 b1 c1 a2 b2 c2 a3 b3 c3 
    

    如果您必须没有添加尾随空格:

    s=""
    for i in 1 2 3; do
        for j in a b c; do
            printf "%s%s%s" "$s" "$j" "$i"
            s=" "
        done
    done
    echo
    

    印刷

    a1 b1 c1 a2 b2 c2 a3 b3 c3
    

    如果您需要对许多值执行此操作,我们需要使用类似于大括号扩展的东西来生成数字列表$(seq 10)。而且,由于 seq 无法生成字母列表,我们需要将生成的数字转换为 ascii:

    s=""
    for i in $(seq 4); do
        for j in $(seq 5); do
            printf "%s\\$(printf %03o $((96+j)))%s" "$s" "$i"
            s=" "
        done
    done
    echo
    

    印刷:

    a1 b1 c1 d1 e1 a2 b2 c2 d2 e2 a3 b3 c3 d3 e3 a4 b4 c4 d4 e4
    
    • 5
  4. Kusalananda
    2019-06-20T13:19:30+08:002019-06-20T13:19:30+08:00
    {a..c}1 {a..c}2 {a..c}3
    

    中的大括号扩展{a..c}{1..3}从左到右扩展,因此您首先得到a{1..3} b{1..3} c{1..3},然后将字母与数字组合成a1 a2 a3 b1 b2 b3 c1 c2 c3. 要获得您想要的订单,您必须使用上面稍长的表达式。

    • 3
  5. jesse_b
    2019-06-20T13:21:09+08:002019-06-20T13:21:09+08:00

    使用循环:

    for n in {1..3}; do printf '%s\n' {a..c}"$n"; done
    

    这将循环通过您的第一个扩展,然后用第二个扩展每个字符。

    如果您需要在一行上全部输出,则可以删除\n:

    for n in {1..3}; do printf '%s ' {a..c}"$n"; done
    

    这不会给你一个尾随换行符,但如果你将它传递给一个不应该成为问题的命令或变量。

    • 2
  6. Dennis Williamson
    2019-06-23T05:36:43+08:002019-06-23T05:36:43+08:00

    这适用于您的简单案例并且可以扩展,但它很快就会失控。这不适用的更复杂的情况很容易构建。

    反转大括号展开的顺序,然后交换字符:

    echo {1..3}{a..c} | sed -E 's/(.)(.)( ?)/\2\1\3/g'
    
    • 2
  7. Hopping Bunny
    2019-06-26T18:03:30+08:002019-06-26T18:03:30+08:00

    一种简单的方法是使用排序(1.2,1.2 表示您在第二个位置取一个字符并在同一位置结束)。

    $ for i in {a..c}{1..3}; do echo $i; done|sort -n -k1.2,1.2
    a1
    b1
    c1
    a2
    b2
    c2
    a3
    b3
    c3
    
    

    如果您希望它们在一行中,您可以像这样使用 tr:

    $ for i in {a..c}{1..3}; do echo $i; done|sort -n -k1.2,1.2|tr '\n' ' '
    a1 b1 c1 a2 b2 c2 a3 b3 c3
    
    • 0
  8. Praveen Kumar BS
    2019-06-21T08:44:56+08:002019-06-21T08:44:56+08:00

    通过以下方法完成

    for i in {1..10}; do for j in {a..c}; do echo $j$i; done; done| perl -pne "s/\n/ /g"
    

    输出

    a1 b1 c1 a2 b2 c2 a3 b3 c3 a4 b4 c4 a5 b5 c5 a6 b6 c6 a7 b7 c7 a8 b8 c8 a9 b9 c9 a10 b10 c10
    
    • -2

相关问题

  • 通过命令的标准输出以编程方式导出环境变量[重复]

  • 从文本文件传递变量的奇怪问题

  • 虽然行读取保持转义空间?

  • `tee` 和 `bash` 进程替换顺序

  • 运行一个非常慢的脚本直到它成功

Sidebar

Stats

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

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

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

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve