Error de argumento del comando AWK

Error de argumento del comando AWK

Tengo un conjunto de datos que contiene información de contacto de los estudiantes, el conjunto de datos de muestra es el siguiente

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

Estoy ejecutando el siguiente comando para reemplazar,dentro de la columna Dirección para|para cargarlo en la base de datos.

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

El problema al que me enfrento es que cada vez que ejecuto este comando me devuelve el siguiente error: Inicialmente se estaba ejecutando bien

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

¿Hay alguna solución para eso? Me di cuenta que%viene en la dirección, ¿ese es el problema?

Respuesta1

  1. Para mayor solidez, nunca lo haga printf $0, utilícelo siempre printf "%s", $0, ya que el primero fallará cuando su entrada contenga printfcaracteres de formato (como está viendo actualmente). Lo mismo se aplica al uso printfcon cualquier dato de entrada.
  2. Para mayor claridad y solidez, nunca utilice nombres de variables totalmente en mayúsculas, por ejemplo, RFSpara evitar conflictos con nombres de variables integradas y para evitar ofuscar su código haciendo que parezca que está utilizando una variable integrada cuando no es así.
  3. Para facilitar la lectura, no establezca variables, por ejemplo RS, después de su secuencia de comandos a menos que necesite establecerlas en diferentes valores para diferentes archivos de entrada, establezca variables antes o al inicio de su secuencia de comandos para que cuando leamos su secuencia de comandos veamos que se configuran antes que nosotros. ver cómo se utilizan.
  4. Por eficiencia, simplicidad y solidez, el primer argumento de *sub() es una expresión regular, no una cadena, así que use delimitadores de expresiones regulares ( /.../), no de cadenas ( "..."), a menos que NECESITE una expresión regular dinámica en lugar de estática por alguna razón.
  5. Para mayor claridad y facilidad de mantenimiento, cuando tenga 2 variables que deben tener el mismo valor, por ejemplo, RSy RFS, no las establezca por separado con el mismo valor, por ejemplo RS="\""; RFS="\"", configúrelas juntas con ese valor, por ejemplo, RS=RFS="\""o establezca una con la otra, por ejemplo. RS="\""; RFS=RS.

Así es como se escribe correctamente el código de su pregunta:

$ 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 hacer más que eso con un CSV usando awk, consulte¿cuál-es-la-forma-más-sólida-de-analizar-csv-eficientemente-usando-awk?.

Respuesta2

El error que te sale se debe a que utilizas la concatenación del valor de RFS(una variable vacía) y $0como cadena de formato con printf.

Su archivo es un archivo CSV válido, además de tener espacios después de algunas de las comas delimitadoras (lo que estropea las comillas del Addresscampo; un campo entre comillas debe tener el carácter de comillas inicial directamente después del delimitador). Podemos corregir esto usando csvformat(parte de 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

Una base de datos que pueda analizar CSV debería poder leer esto tal como está.

¿Aún desea reemplazar todas las comas incrustadas en |? Simplemente cambie el delimitador del archivo a algo que no sea una coma (usaré tabulaciones a continuación), cambie todas las comas restantes a barras verticales y vuelva a usar comas como delimitadores.

Podemos hacer esto directamente sobre los datos originales:

$ 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

Las variantes cortas de las distintas opciones largas utilizadas son -Sfor --skipinitialspace, -Tfor --out-tabsy -tfor --tabs.

información relacionada