AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 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

Aplique a expansão da chave em "ordem inversa"

  • 772

Por exemplo {a..c}{1..3}, expande para a1 a2 a3 b1 b2 b3 c1 c2 c3.

Se eu quisesse imprimir a1 b1 c1 a2 b2 c2 a3 b3 c3, existe uma maneira análoga de fazer isso? Qual é a maneira mais simples?

bash brace-expansion
  • 8 8 respostas
  • 1489 Views

8 respostas

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

    Você poderia fazer:

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

    Que então diz ao shell para avaliar:

    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

    Para este caso em particular, acho que a opção dada por Stéphane Chazelas é a melhor.

    Por outro lado, quando você expande coisas mais complexas, essa opção não escala bem. Então, você pode conseguir o mesmo com isso:

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

    que retorna:

    a1 b1 c1 a2 b2 c2 a3 b3 c3
    

    Parece um pouco confuso, mas agora, tenho um controle enorme na ordem, apenas alterando dois chars no comando acima; por exemplo:

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

    isso se expandirá para:

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

    Suponha que eu queira todos os 1na segunda expansão, então o 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
    

    Suponha que eu queira todos os ana terceira expansão, então o 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
    

    Suponha que eu queira todos os 1na quarta expansão, então o 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
    

    Suponha que eu queira tudo 1ano meio, então 1b, então 2a, então 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
    

    Você pode até mesmo, com a mesma facilidade, reverter qualquer ordem nas expansões acima, apenas adicionando um rao comando anterior; por exemplo, o último:

    $ 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
    

    Nota_1 : normalmente, se esta expansão final for usada como uma lista de argumentos, o espaço à direita não é um problema; mas se você quiser se livrar dele, você pode adicionar, a qualquer um dos comandos acima, por exemplo| sed 's/ $//' ; ou mesmo| sed 's/ $/\n/', para alterar esse espaço à direita por umnewline

    Nota_2 : Nos exemplos acima, usei subconjuntos de dois elementos (ou seja: {a,b} e {1,2} ) apenas para simplificar na prova de conceito: você pode usar subconjuntos de qualquer comprimento finito e o comando correspondente, seria comparável.

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

    bash, ksh, zsh

    Um forro que funciona em (bash, ksh, zsh) (nem todos os shells podem fazer "expansão de chaves" na ordem inversa):

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

    Uma alternativa que usa eval(que ainda é para bash, ksh, zsh e pode ser mais enigmática) é:

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

    Para entender o que acontece, substitua evalpor echo:

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

    O comando executado (após a expansão eval) é na verdade echo {a..c}1 {a..c}2 {a..c}3. Que se expande conforme você quer/precisa.

    todas as conchas

    Existem vários shells sem "expansões de chaves", portanto, não é possível usar isso para "todos os shells". Precisamos de um loop (com um espaço em branco à direita):

    $ 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 
    

    Se você não deve ter nenhum espaço à direita adicionado:

    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
    

    Impressões

    a1 b1 c1 a2 b2 c2 a3 b3 c3
    

    SE você precisar fazer isso para muitos valores, precisamos usar algo semelhante à expansão de chaves para gerar uma lista de números $(seq 10). E, como seq não consegue gerar uma lista de letras, precisamos converter para ascii os números gerados:

    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
    

    imprime:

    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
    

    As expansões de chaves {a..c}{1..3}são expandidas da esquerda para a direita, então você primeiro obtém a{1..3} b{1..3} c{1..3}e, em seguida, as letras são combinadas com os números em a1 a2 a3 b1 b2 b3 c1 c2 c3. Para obter a ordem desejada, você terá que usar a expressão um pouco mais longa acima.

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

    Usando um laço:

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

    Isso fará um loop pela sua primeira expansão e, em seguida, expandirá cada caractere com a segunda.

    Se você precisar da saída toda em uma linha, poderá remover o \n:

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

    Isso não lhe dará uma nova linha à direita, mas se você estiver passando para um comando ou variável, isso não deve ser um problema.

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

    Isso funciona para o seu caso simples e pode ser estendido, mas rapidamente sairia do controle. Casos mais complexos para os quais isso não funcionaria são fáceis de construir.

    Inverta a ordem das expansões de chaves e troque os caracteres:

    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

    Um método simples seria usar sort (o 1.2,1.2 significa que você pega um caractere na segunda posição e termina no mesmo lugar).

    $ 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
    
    

    Se você quiser eles em uma linha, você pode usar tr assim:

    $ 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

    Feito pelo método abaixo

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

    resultado

    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

relate perguntas

  • exportar variáveis ​​​​env programaticamente, via stdout do comando [duplicado]

  • Problema estranho ao passar variáveis ​​do arquivo de texto

  • Enquanto a linha lê mantendo os espaços de escape?

  • ordem de substituição de processos `te` e `bash`

  • Execute um script muito lento até que seja bem-sucedido

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

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

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve