Erro de argumento de comando AWK

Erro de argumento de comando AWK

Eu tenho um conjunto de dados que contém informações de contato de alunos. O conjunto de dados de amostra é o seguinte

First Name, Last Name, Address, Phone Number
John, Doe, "House # 11, Street xyz, Road, Area",00000000
Sara, Taylor, "Jake Lake%, Apartment #22, Main Road, Area XYZ", 00000000

Estou executando o seguinte comando para substituir,dentro da coluna Endereço para|para carregá-lo no banco de dados.

awk '!(NR%2){gsub(",","|")} {printf RFS $0} {RFS="\""}' RS=\" fileName.txt > output.txt

O problema que estou enfrentando é que sempre que executei este comando ele me retornou o seguinte erro: Inicialmente estava rodando ok

awk: run time error: not enough arguments passed to printf(""Jake Lake%, Apartment #22, Main Road, Area XYZ")

Existe alguma solução para isso? eu percebi isso%está chegando no endereço, esse é o problema?

Responder1

  1. Para maior robustez, nunca do printf $0, sempre use printf "%s", $0em vez disso, pois o primeiro falhará quando sua entrada contiver printfcaracteres de formatação (como você está vendo atualmente). O mesmo se aplica ao uso printfcom quaisquer dados de entrada.
  2. Para maior clareza e robustez, nunca use nomes de variáveis ​​​​com letras maiúsculas, por exemplo, RFSpara evitar conflitos com nomes de variáveis ​​incorporadas e para evitar ofuscar seu código, fazendo parecer que você está usando uma variável incorporada quando não está.
  3. Para facilitar a leitura, não defina variáveis, por exemplo RS, depois do seu script, a menos que você precise defini-las com valores diferentes para arquivos de entrada diferentes, defina variáveis ​​antes ou no início do seu script para que, ao ler o seu script, vejamos elas sendo definidas antes de nós vê-los sendo usados.
  4. Para eficiência, simplicidade, robustez, o primeiro argumento para *sub() é um regexp, não uma string, então use delimitadores regexp ( /.../), e não string ( "..."), a menos que você PRECISE de um regexp dinâmico em vez de estático por algum motivo.
  5. Para maior clareza e facilidade de manutenção, quando você tiver 2 variáveis ​​que devem ter o mesmo valor, por exemplo, RSe RFS, não as defina separadamente com o mesmo valor, por exemplo RS="\""; RFS="\"", configure-as juntas para esse valor, por exemplo, RS=RFS="\""ou defina uma para a outra, por exemplo RS="\""; RFS=RS.

Veja como escrever o código da sua pergunta corretamente:

$ awk -v RS='"' '!(NR%2){gsub(/,/,"|")} {printf "%s%s", rfs, $0; rfs=RS}' file
First Name, Last Name, Address, Phone Number
John, Doe, "House # 11| Street xyz| Road| Area",00000000
Sara, Taylor, "Jake Lake%| Apartment #22| Main Road| Area XYZ", 00000000

Para fazer mais do que isso com um CSV usando o awk, consultequal é a maneira mais robusta de analisar com eficiência o csv usando o awk.

Responder2

O erro que você obtém é devido ao uso da concatenação do valor de RFS(uma variável vazia) e $0como string de formato com printf.

Seu arquivo é um arquivo CSV válido, além de ter espaços após algumas vírgulas delimitadoras (o que atrapalha a citação do Addresscampo; um campo entre aspas precisa ter o caractere de aspa inicial diretamente após o delimitador). Podemos corrigir isso usando csvformat(parte do csvkit dehttps://csvkit.readthedocs.io/en/latest/):

$ csvformat --skipinitialspace file.csv >fixed-file.csv
$ cat fixed-file.csv
First Name,Last Name,Address,Phone Number
John,Doe,"House # 11, Street xyz, Road, Area",00000000
Sara,Taylor,"Jake Lake%, Apartment #22, Main Road, Area XYZ",00000000

Um banco de dados que possa analisar CSV deve ser capaz de ler isso como está.

Você ainda deseja substituir todas as vírgulas incorporadas por |, simplesmente altere o delimitador do arquivo para algo diferente de uma vírgula (usarei as guias abaixo), altere todas as vírgulas restantes para barras verticais e volte a usar vírgulas como delimitadores novamente.

Podemos fazer isso diretamente nos dados originais:

$ csvformat --skipinitialspace --out-tabs file.csv | tr ',' '|' | csvformat --tabs >fixed-file.csv
$ cat fixed-file.csv
First Name,Last Name,Address,Phone Number
John,Doe,House # 11| Street xyz| Road| Area,00000000
Sara,Taylor,Jake Lake%| Apartment #22| Main Road| Area XYZ,00000000

As variantes curtas das várias opções longas usadas são -Sfor --skipinitialspace, -Tfor --out-tabse -tfor --tabs.

informação relacionada