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 / 454912
Accepted
Spike
Spike
Asked: 2018-07-13 06:11:08 +0800 CST2018-07-13 06:11:08 +0800 CST 2018-07-13 06:11:08 +0800 CST

Como cortar uma string com base no delimitador que está tendo espaço

  • 772
variable_list="
 any:any:-a -b -c any
 one:one:-c -b -f -m mul
 mul:one:-c -b -f -m mul
"
for f in `echo $variable_list`
do
  c1=`echo $f | cut -d':' -f1`;
  c2=`echo $f | cut -d':' -f2`;
  c3=`echo $f | cut -d':' -f3-`;
  echo "c1==>$c1 and c2==>$c2 and c3==>$c3";
  #exit 0; ###I made mistake here
done;

Saída esperada:

c1==>any and c2==>any and c3==>-a -b -c any
c1==>one and c2==>one and c3==>-c -b -f -m mul
c1==>mul and c2==>one and c3==>-c -b -f -m mul

Editar 1:

Percebi que fui estúpido ao usar o script e, na primeira iteração, costumava exit 0testá-lo apenas na primeira linha, pois tenho muito disso na realidade. Estava funcionando como tem que estar.

Posso obter a saída mencionada mantendo o variable_listsem modificar o formato/forma de entrada?

(estou usando bash)

cut
  • 2 2 respostas
  • 2150 Views

2 respostas

  • Voted
  1. Best Answer
    Kusalananda
    2018-07-13T06:49:01+08:002018-07-13T06:49:01+08:00

    Seu problema é com os espaços nos dados. O shell irá dividir a string em palavras em todos os espaços e o forloop irá iterar sobre essas palavras.

    (Para uma solução que não substitui variable_listpor uma matriz, consulte o final desta resposta.)

    Em vez disso, use uma matriz adequada:

    variable_list=(
        "any:any:-a -b -c any"
        "one:one:-c -b -f -m mul"
        "mul:one:-c -b -f -m mul"
    )
    
    for var in "${variable_list[@]}"; do
        c1=$( cut -d':' -f1  <<<"$var" )
        c2=$( cut -d':' -f2  <<<"$var" )
        c3=$( cut -d':' -f3- <<<"$var" )
        printf 'c1==>%s and c2==>%s and c3==>%s\n' "$c1" "$c2" "$c3"
    done
    

    O uso de um array garante que você possa acessar cada conjunto individual de variáveis ​​como sua própria entrada de array sem depender deles serem delimitados por novas linhas ou algum outro caractere.

    O código também está usando "here-strings" bashpara enviar a string para cut(em vez de echoum pipe).

    Ou, muito mais eficientemente,

    variable_list=(
        "any:any:-a -b -c any"
        "one:one:-c -b -f -m mul"
        "mul:one:-c -b -f -m mul"
    )
    
    for var in "${variable_list[@]}"; do
        IFS=':' read -r c1 c2 c3 <<<"$var"
        printf 'c1==>%s and c2==>%s and c3==>%s\n' "$c1" "$c2" "$c3"
    done
    

    A definição IFSde dois pontos para readfará com que reada entrada seja dividida em dois pontos (em vez de espaços, tabulações e novas linhas).

    Observe que toda a citação acima é significativa. Sem as aspas duplas, o shell executaria divisão de palavras e globbing de nome de arquivo nos valores de variable_liste varnas três cvariáveis.

    Relacionado:

    • Quando as aspas duplas são necessárias?
    • Por que printf é melhor que echo?
    • Os backticks (ou seja, `cmd`) em shells *sh foram obsoletos?

    Se tudo o que você procura é essa saída específica, você pode trapacear um pouco:

    variable_list=(
        "any:any:-a -b -c any"
        "one:one:-c -b -f -m mul"
        "mul:one:-c -b -f -m mul"
    )
    
    ( IFS=':'; set -f; printf 'c1==>%s and c2==>%s and c3==>%s\n' ${variable_list[@]} )
    

    Isso executa o printfem um subshell para que a configuração IFSe a opção do shell -f( noglob) não afetem o restante do script. Definir IFSdois pontos aqui fará com que o shell expanda a matriz sem aspas variable_list em três conjuntos de três argumentos para printf. printfimprimirá os três primeiros de acordo com sua string de formato e, em seguida, reutilizará esse formato para o próximo conjunto de três argumentos, até que todos os argumentos tenham sido processados.

    O set -fimpede que a expansão sem aspas de acione o variable_listglobbing de nome de arquivo, caso haja algum caractere de globbing de nome de arquivo lá.


    Usando uma string delimitada por nova linha:

    variable_list="
    any:any:-a -b -c any
    one:one:-c -b -f -m mul
    mul:one:-c -b -f -m mul"
    
    while IFS= read -r var; do
        IFS=':' read -r c1 c2 c3 <<<"$var"
        printf 'c1==>%s and c2==>%s and c3==>%s\n' "$c1" "$c2" "$c3"
    done <<<"$variable_list"
    

    Isso lê os dados da string como se viessem de um arquivo.

    Relacionado:

    • Entendendo "IFS= read -r line"
    • 5
  2. ctac_
    2018-07-13T10:29:08+08:002018-07-13T10:29:08+08:00

    Você pode usar awk para obter sua saída:

    echo "$variable_list" | awk -F: '
    {
      sub("^ ","")
      for(i=1;i<=NF;i++)
        sub(/^/,"c" i "==>",$i)
    }1' OFS=" and "
    
    • 0

relate perguntas

  • "Nenhum arquivo ou diretório" ao usar "-exec" com find

  • Corte as duas primeiras linhas

  • Corte e substitua uma coluna específica de uma lista de arquivos

  • sort Descubra quantos valores distintos existem em determinada coluna

  • Existe uma alternativa de substituição/expansão de parâmetro para "| cut -f1,2,3 -d:" também conhecido como trim após e incluindo a n-ésima ocorrência de caractere?

Sidebar

Stats

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

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

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 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

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 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
    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
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +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
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +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