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 / coding / Perguntas / 77481565
Accepted
Sam
Sam
Asked: 2023-11-14 22:50:44 +0800 CST2023-11-14 22:50:44 +0800 CST 2023-11-14 22:50:44 +0800 CST

Linux Substitua a coluna inteira por um novo valor em todas as linhas múltiplas

  • 772

Eu tenho as seguintes linhas em um arquivo

$ cat test.txt
69|1074330570|1,sip:+121345633210x3Bverstat=TN-Validation-Passed|tel:+12134565534|0
69|1077822111|2,;tel:+2223120011~sip:[email protected];|sip:[email protected]|0
69|1077988012|1,sip:+121510016070x3Bverstat=TN-Validation-Passed|tel:+136965339510x3Bnpd|0

Quero substituir a terceira e a quarta colunas do arquivo apenas por números de telefone, da seguinte forma:

69|1074330570|2134563321|2134565534|0
69|1077822111|2223120011|3123120022|0
69|1077988012|2151001607|3696533951|0

A parte boa é que todos os arquivos terão um ‘+’ na terceira e quarta colunas. Agora, a parte difícil é que às vezes obtemos 11 dígitos, conforme observado na terceira coluna da primeira linha (121345633210) e às vezes não há '1' adicionado após um '+'. Portanto, se houver 1 após o sinal de mais, exclua 1. Caso contrário, inicie o comprimento após o sinal '+'. Da mesma forma, se houver 11 dígitos, apenas a substring 10. Além disso, se houver mais de 1 número como a linha 2, preciso pegar o primeiro número após o sinal '+' apenas como 2223120011 e não 2223120051.

Eu tentei o seguinte

awk -F"|"  'BEGIN {FS="+"}{print substr($3,2,10)}' test.txt

Mas está fornecendo um valor incorreto para a segunda linha, pois precisa começar após o sinal '+'.

regex
  • 4 4 respostas
  • 96 Views

4 respostas

  • Voted
  1. Best Answer
    markp-fuso
    2023-11-14T23:14:28+08:002023-11-14T23:14:28+08:00

    Problemas com o código atual:

    • -F"|"e FS="+"ambos definem o delimitador do campo de entrada, portanto, tecnicamente, você deve escolher um ou outro, mas não ambos; neste caso FS="+"tem precedência (ou seja, -F"|"é ignorado)
    • como o requisito geral é 'substituir' a 3ª e a 4ª colunas, você desejará manter o -F"|", mas também defini-lo como o delimitador do campo de saída (recomende:BEGIN { FS=OFS="|"}
    • em seguida, analise mais detalhadamente os 3º/4º campos com alguma combinação de awkfunções de string (por exemplo, split(), match(), index(), substr())

    Suposições/Entendimentos:

    • 3º/4º campos sempre têm um+
    • a string após o +é sempre um número de 10 ou 11 dígitos
    • se o terceiro/quarto campo tiver mais de um +, estaremos interessados ​​apenas no primeiro + (por exemplo, não precisamos analisar mais com base em telor sip)
    • parece que estamos lidando com formatos de números de telefone norte-americanos (por exemplo, não precisamos nos preocupar com os diferentes formatos de números de telefone de outros países)

    Uma awkideia:

    awk '
    BEGIN { FS=OFS="|" }
          { for (i=3; i<=4; i++) {                         # loop through 3rd and 4th fields
                split($i,a,"+")                            # split on "+"
                d1 = substr(a[2],1,1)                      # get 1st digit after the "+"
                $i = substr(a[2],(d1==1 ? 2 : 1),10)       # redefine ith field based on value of 1st digit
            }
          }
    1                                                      # print current line
    ' test.txt
    

    NOTAS:

    • essa lógica é codificada com base nas suposições de que só temos que lidar com formatos de números de telefone norte-americanos (10 dígitos/11 dígitos, código do país = 1)

    Isso gera:

    69|1074330570|2134563321|2134565534|0
    69|1077822111|2223120011|3123120022|0
    69|1077988012|2151001607|3696533951|0
    
    • 4
  2. anubhava
    2023-11-14T23:19:20+08:002023-11-14T23:19:20+08:00

    Você pode usar esta awksolução:

    awk '
    function extphone(s) {
       sub(/^[^+]*\+1?/, "", s)  # remove all text before + then + and optional 1
       return substr(s, 1, 10)   # extract first 10 characters now
    }
    BEGIN {FS=OFS="|"}
    {
       $3 = extphone($3)
       $4 = extphone($4)
    } 1' file
    
    69|1074330570|2134563321|2134565534|0
    69|1077822111|2223120011|3123120022|0
    69|1077988012|2151001607|3696533951|0
    
    • 4
  3. Ed Morton
    2023-11-14T23:33:51+08:002023-11-14T23:33:51+08:00

    Com GNU awk para gensub():

    $ awk '
        BEGIN { FS=OFS="|" }
        {
            for ( i=3; i<=4; i++ ) {
                $i = gensub(/[^+]+\+1?([0-9]{10}).*/,"\\1",1,$i)
            }
            print
        } 
    ' test.txt
    69|1074330570|2134563321|2134565534|0
    69|1077822111|2223120011|3123120022|0
    69|1077988012|2151001607|3696533951|0
    

    ou com qualquer awk:

    $ awk '
        BEGIN { FS=OFS="|" }
        {
            for ( i=3; i<=4; i++ ) {
                if ( match($i,/\+1?[0-9]{10}/) ) {
                    $i = substr($i,RSTART+RLENGTH-10,10)
                }
            }
            print
        }
    ' test.txt
    69|1074330570|2134563321|2134565534|0
    69|1077822111|2223120011|3123120022|0
    69|1077988012|2151001607|3696533951|0
    
    • 2
  4. RavinderSingh13
    2023-11-15T07:16:25+08:002023-11-15T07:16:25+08:00

    Com os exemplos mostrados, tente seguir awko código GNU.

    awk '
    match($0,/^([^|]*\|[^|]*\|)[^+]*\+1*([0-9]+)[^|]*(\|)[^+]*\+1*([0-9]+)[^|]*(\|.*$)/,arr){
      sub(/0$/,"",arr[2])
      sub(/0$/,"",arr[4])
      print arr[1] arr[2] arr[3] arr[4] arr[5]
    }
    '  Input_file
    

    Explicação: Adicionando explicação detalhada para o código acima.

    • Usando a função GNU awkpara matchusar regex nele, que cria grupos de captura e mais tarde podemos usá-los para obter a saída necessária.
    • Usando regex ^([^|]*\|[^|]*\|)[^+]*\+1*([0-9]+)[^|]*(\|)[^+]*\+1*([0-9]+)[^|]*(\|.*$)dentro matchda função.
    • Se uma correspondência de regex for encontrada, remova 0pelo menos o segundo e o quarto grupo de captura usando subaqui.
    • Em seguida, imprima todos os 5 grupos de captura para obter a saída necessária.
    • 1

relate perguntas

  • Regex: Corresponde até "," mas não se "," estiver entre colchetes

  • encontre o número enésimo da string e divida o ['8','th'] assim usando dart

  • Faça uma nova linha após 3 caracteres após regex

  • Antevisão positiva no regex do Google Sheets

  • Como usar a renomeação do Perl no terminal do macOS para substituir nomes de arquivos aleatórios por string e índice personalizados?

Sidebar

Stats

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

    destaque o código em HTML usando <font color="#xxx">

    • 2 respostas
  • Marko Smith

    Por que a resolução de sobrecarga prefere std::nullptr_t a uma classe ao passar {}?

    • 1 respostas
  • Marko Smith

    Você pode usar uma lista de inicialização com chaves como argumento de modelo (padrão)?

    • 2 respostas
  • Marko Smith

    Por que as compreensões de lista criam uma função internamente?

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Marko Smith

    java.lang.NoSuchMethodError: 'void org.openqa.selenium.remote.http.ClientConfig.<init>(java.net.URI, java.time.Duration, java.time.Duratio

    • 3 respostas
  • Marko Smith

    Por que 'char -> int' é promoção, mas 'char -> short' é conversão (mas não promoção)?

    • 4 respostas
  • Marko Smith

    Por que o construtor de uma variável global não é chamado em uma biblioteca?

    • 1 respostas
  • Marko Smith

    Comportamento inconsistente de std::common_reference_with em tuplas. Qual é correto?

    • 1 respostas
  • Marko Smith

    Somente operações bit a bit para std::byte em C++ 17?

    • 1 respostas
  • Martin Hope
    fbrereto Por que a resolução de sobrecarga prefere std::nullptr_t a uma classe ao passar {}? 2023-12-21 00:31:04 +0800 CST
  • Martin Hope
    比尔盖子 Você pode usar uma lista de inicialização com chaves como argumento de modelo (padrão)? 2023-12-17 10:02:06 +0800 CST
  • Martin Hope
    Amir reza Riahi Por que as compreensões de lista criam uma função internamente? 2023-11-16 20:53:19 +0800 CST
  • Martin Hope
    Michael A formato fmt %H:%M:%S sem decimais 2023-11-11 01:13:05 +0800 CST
  • Martin Hope
    God I Hate Python std::views::filter do C++20 não filtrando a visualização corretamente 2023-08-27 18:40:35 +0800 CST
  • Martin Hope
    LiDa Cute Por que 'char -> int' é promoção, mas 'char -> short' é conversão (mas não promoção)? 2023-08-24 20:46:59 +0800 CST
  • Martin Hope
    jabaa Por que o construtor de uma variável global não é chamado em uma biblioteca? 2023-08-18 07:15:20 +0800 CST
  • Martin Hope
    Panagiotis Syskakis Comportamento inconsistente de std::common_reference_with em tuplas. Qual é correto? 2023-08-17 21:24:06 +0800 CST
  • Martin Hope
    Alex Guteniev Por que os compiladores perdem a vetorização aqui? 2023-08-17 18:58:07 +0800 CST
  • Martin Hope
    wimalopaan Somente operações bit a bit para std::byte em C++ 17? 2023-08-17 17:13:58 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

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