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 / 789631
Accepted
peti27
peti27
Asked: 2025-01-16 00:20:57 +0800 CST2025-01-16 00:20:57 +0800 CST 2025-01-16 00:20:57 +0800 CST

Como selecionar uma string delimitada por dois padrões de string diferentes

  • 772

Estou tendo uma saída semelhante ao arquivo (nome do arquivo qualquer.com) abaixo...

[...]~ # tmsh list sys file ssl-cert whatever.com_2024
sys file ssl-cert whatever.com_2024 {
    certificate-key-size 2048
    checksum SHA1:2520:ab40df7776dbbccb62345560511f2205d
    create-time 2024-08-12:19:34:07
    created-by x.y
    expiration-date 1754956799
    expiration-string "Aug 11 23:59:59 2025 GMT"
    fingerprint SHA256/D8:57:8E:8E:4A:1A:C3:3C:1B:6F:32:59:A7:36:66:92:6C
    issuer "CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1,O=DigiCert Inc,C=US"
    key-type rsa-public
    last-update-time 2024-08-12:19:34:07
    mode 33188
    revision 1
    serial-number 0a:1d:ca:c7:09:7b:49:59:b2
    size 2520
    source-path /var/run/key_mgmt/RvGubB/ssl.crt/whatever.com_2024
    subject "CN=whatever.com,O=XYZ,L=Toronto,ST=Ontario,C=CA"
    subject-alternative-name "DNS:whatever.com"
    updated-by x.y
    version 3

Estou tentando gerar uma saída de comando com base nas informações acima na linha 17 (começando com o assunto)

cat whatever.com | awk 'BEGIN  {F=" "; FS = "\n"; RS = ""; OFS = "\n"} { print "openssl req -new -nodes -sha256 -newkey rsa:2048 -out "substr($1,RSTART+19,length($1)-25)"_2025.csr -keyout "substr($1,RSTART+19,length($1)-25)"_2025.key -subj "/"substr($17,RSTART+14,length($17)-14)"\""}'

A saída está parecendo boa

openssl req -new -nodes -sha256 -newkey rsa:2048 -out whatever.com_2025.csr -keyout whatever.com_2025.key -subj "/CN=whatever.com,O=XYZ,L=Toronto,ST=Ontario,C=CA"

No entanto, ele está usando uma substring da linha 1 que pode ser diferente da linha 17, então eu gostaria de obter o nome do arquivo em vez de usar substr($1,RSTART+19,length($1)-24) para ser gerado com base na string do formulário $17 entre "CN=" e ",O=".

Também seria possível modificar a saída para ficar assim se a linha 18 contivesse a string "DNS"...

openssl req -new -nodes -sha256 -newkey rsa:2048 -out whatever.com_2025.csr -keyout whatever.com_2025.key -subj "/CN=whatever.com,O=XYZ,L=Toronto,ST=Ontario,C=CA" -addext "subjectAltName = DNS:whatever.com"

Obrigado por todas as respostas rápidas. Os nomes de arquivo devem ser gerados dinamicamente a partir do arquivo. O exemplo incluso é apenas uma pequena seção da saída maior. A configuração BEGIN está lá para criar essas seções que, nesse ponto, podem ser manipuladas individualmente por linha.

Lidando com balanceadores de carga F5. Eles são baseados em Linux, mas não são exatamente construídos como servidores normais, o que torna alguns dos scripts desafiadores.

Eu encontrei uma solução usando split() mas agora tenho um problema diferente. Quando eu executo o comando sozinho, parece funcionar

 ~ # cat whatever.com | awk 'BEGIN  {F=" "; FS = "\n"; RS = ""; OFS = "\n"} {split($17,a,/,/); print substr(a[1],RSTART+17)}'
whatever.com

Entretanto, quando adicionado ao script original, ele acrescenta o número "5" na frente.

 ~ # cat whatever.com |  awk 'BEGIN  {F=" "; FS = "\n"; RS = ""; OFS = "\n"} { print "openssl req -new -nodes -sha256 -newkey rsa:2048 -out "split($17,a,/,/); print substr(a[1],RSTART+17)"_2025.csr -keyout "split($17,a,/,/); print substr(a[1],RSTART+17)"_2025.key -subj \"/"substr($17,RSTART+14,length($17)-14)"\""}' 

openssl req -new -nodes -sha256 -newkey rsa:2048 -out 5
whatever.com_2025.csr -keyout 5
whatever.com_2025.key -subj "/CN=whatever.com,O=XYZ,L=Toronto,ST=Ontario,C=CA"
awk
  • 4 4 respostas
  • 84 Views

4 respostas

  • Voted
  1. ilkkachu
    2025-01-16T00:58:13+08:002025-01-16T00:58:13+08:00

    Eu provavelmente processaria as linhas uma por uma como de costume, e olharia para o primeiro campo separado por espaços para identificar as linhas de assunto e alt-name. Então, você pode dividir a linha em outro array usando a pontuação e escolher a parte certa de lá. (Isso pressupõe que não haja nada antes da CNparte -- não consigo lembrar se isso seria permitido.) Se você quiser realmente verificar o texto ao redor (as partes CN=e ), então eu mudaria para Perl e veria a resposta do meuh .DNS:

    
    awk '$1 == "subject" { subject=$2; split($2, a, "[=,]"); cn=a[2]; } 
         $1 == "subject-alternative-name" { split($2, a, "[\":]"); altname=a[3]; }
         END { out = "openssl ... -keyout " cn "_2025.key -subj "  subject; 
               if (altname) out = out " -altname \"subjectAltName = DNS:" altname "\"";
               print out 
         } '  < whatever.txt
    openssl ... -keyout foo.whatever.com_2025.key -subj "CN=foo.whatever.com,O=XYZ,L=Toronto,ST=Ontario,C=CA" -altname "subjectAltName = DNS:bar.whatever.com"
    
    • 1
  2. Best Answer
    meuh
    2025-01-16T01:20:20+08:002025-01-16T01:20:20+08:00

    Use GNU awk's match(string, regexp, arrayresult)com a ()no regexp para capturar a parte desejada. Por exemplo

    awk '
    BEGIN  {F=" "; FS = "\n"; RS = ""; OFS = "\n"}
    { match($17, "CN=([^,]*)", x);
      cn = x[1]
      match($17, "\"(.*)\"", x)
      subject = x[1]
      if(match($18, "(DNS:.*)\"", x)>0){
       dns = x[1]
       toadd = " -addext \"subjectAltName = " dns "\""
      }
      print "openssl req -new -nodes -sha256 -newkey rsa:2048 -out " \
       cn "_2025.csr -keyout " \
       cn "_2025.key -subj \"/" \
       subject "\"" toadd
    }'
    
    • 1
  3. markp-fuso
    2025-01-16T01:23:23+08:002025-01-16T01:23:23+08:00

    Para responder à pergunta do OP sobre por que seu código está usando dados de line 1... verifique o conteúdo de RSTART. Você deve encontrar RSTART=0porque nenhuma função (por exemplo, match()) foi executada para realmente preencher RSTART.

    Em vez de tentar processar a saída inteira como um parágrafo, sugiro processá-la como linhas individuais.

    Uma awkabordagem diferente:

    $ cat whatever.com | awk -F'"' '            # set double quotes as field delimiter
    { gsub(/[[:space:]]/,"",$1)                 # trim white space from 1st field
      if ($1=="subject")
         subject=$2                             # save for later use
      else
      if ($1=="subject-alternative-name")
         print "openssl req -new -nodes -sha256 -newkey rsa:2048 -out whatever.com_2025.csr -keyout whatever.com_2025.key -subj \"/" subject "\" -addext \"subjectAltName = " $2 "\""
    }'
    

    Isso gera:

    openssl req -new -nodes -sha256 -newkey rsa:2048 -out whatever.com_2025.csr -keyout whatever.com_2025.key -subj "/CN=whatever.com,O=XYZ,L=Toronto,ST=Ontario,C=CA" -addext "subjectAltName = DNS:whatever.com"
    
    • 0
  4. Vercingatorix
    2025-01-16T02:07:18+08:002025-01-16T02:07:18+08:00

    Isso pressupõe que você pode processar linha por linha e não fazer todas as contorções de campo e registro que você fez. Também pressupõe que subject-alternative-nameestá sempre presente:

    # Capture domain name in "subject" field, which starts with "CN=" and ends with a comma, and whole field too
    / +subject .*CN=[^,]+,O=/ {
      match($2, /"(CN=([^,]+),O=[^"]+")/, arr);
      domain=arr[2];
    }
    
    # Only print once we ascertain whether "DNS" is present in "subject-alternative-name" field
    / +subject-alternative-name / {
      # If we have "DNS" keyword, print with "-addext", otherwise print without
      if (match($2, /"(DNS:[^"]+)/, altarr))
        printf "openssl req -new -nodes -sha256 -newkey rsa:2048 -out %s_2025.csr -keyout %s_2025.key -subj \"/%s -addext \"subjectAltName = %s\"\n", domain, domain, arr[1], altarr[1];
      else
        printf "openssl req -new -nodes -sha256 -newkey rsa:2048 -out %s_2025.csr -keyout %s_2025.key -subj \"/%s\n", domain, domain, arr[1];
    }
    

    Com a DNSpalavra-chave:

    $ awk -f /tmp/UL_789631.awk < /tmp/UL_789631.txt 
    openssl req -new -nodes -sha256 -newkey rsa:2048 -out whatever.com_2025.csr -keyout whatever.com_2025.key -subj "/CN=whatever.com,O=XYZ,L=Toronto,ST=Ontario,C=CA" -addext "subjectAltName = DNS:whatever.com"
    

    Sem a DNSpalavra-chave:

    $ awk -f /tmp/UL_789631.awk < /tmp/UL_789631.txt 
    openssl req -new -nodes -sha256 -newkey rsa:2048 -out whatever.com_2025.csr -keyout whatever.com_2025.key -subj "/CN=whatever.com,O=XYZ,L=Toronto,ST=Ontario,C=CA"
    

    Isso usa subexpressões de expressão regular para capturar a parte relevante. A matchfunção faz uma correspondência de expressão regular e atribui as subexpressões (aquelas entre parênteses) a um array (aqui, arrpara o subjectcampo e altarrpara o subject-alternative-namecampo). Usamos duas subexpressões (sobrepostas) para subject: uma para o valor do campo e uma para o nome do domínio dentro do valor do campo.

    A primeira /.../ {linha corresponde ao campo assunto (note os espaços para que não corresponda ao outro campo que começa com 'assunto'). O primeiro parêntesis do matchextrai o conteúdo do campo, e o segundo o nome do domínio.

    O propósito do [^,]+é combinar tudo até e excluindo o (próximo) delimitador de vírgula de uma forma não gananciosa. Se você usasse .+,, ele capturaria tudo até C=CA.

    Na conclusão desta correspondência, arrcontém o regex inteiro, a string de campo e a string de domínio.

    Ainda não imprimimos porque ainda não sabemos o que incluir. (Você também pode imprimir uma linha parcial, se quiser, e adicionar um END { printf "\n"}.)

    A correspondência do / +subject-alternative-name analisa o segundo campo para a DNSpalavra-chave, capturando todo o valor do campo e, se corresponder, imprime o comando estendido apropriado; caso contrário, imprime o comando regular.

    Bom despertar!

    • 0

relate perguntas

  • remova o número de linhas duplicadas com base na correspondência antes da primeira vírgula

  • anexar linhas após outros arquivos linha por linha

  • Como remover uma única linha entre duas linhas

  • Reorganize as letras e compare duas palavras

  • Embaralhamento de arquivo de várias linhas

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