Ошибка аргумента команды AWK

Ошибка аргумента команды AWK

У меня есть набор данных, содержащий контактную информацию студентов, пример набора данных выглядит следующим образом:

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

Я запускаю следующую команду для замены,внутри столбца Адрес в|для загрузки его в БД.

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

Проблема, с которой я столкнулся, заключается в том, что всякий раз, когда я запускаю эту команду, она возвращает мне следующую ошибку. Изначально она работала нормально.

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

Есть ли решение этой проблемы? Я заметил, что%приходит по адресу, в этом проблема?

решение1

  1. Для надежности никогда не делайте printf $0, всегда используйте printf "%s", $0вместо этого , так как первый вариант не сработает, если ваш ввод содержит printfсимволы форматирования (как вы сейчас видите). То же самое относится к использованию printfс любыми входными данными.
  2. Для ясности и надежности никогда не используйте имена переменных, состоящие только из заглавных букв, например, RFSчтобы избежать конфликтов с именами встроенных переменных и чтобы не запутывать код, создавая впечатление, что вы используете встроенную переменную, хотя это не так.
  3. Для удобства чтения не устанавливайте переменные, например RS, после вашего скрипта, если только вам не нужно задать им разные значения для разных входных файлов; устанавливайте переменные до или в начале вашего скрипта, чтобы при чтении вашего скрипта мы видели, как они устанавливаются, прежде чем мы увидим их использование.
  4. Для эффективности, простоты и надежности первым аргументом *sub() является регулярное выражение, а не строка, поэтому используйте вокруг него разделители regexp ( /.../), а не string ( "..."), если только по какой-то причине вам НЕ НУЖНО динамическое, а не статическое регулярное выражение.
  5. Для ясности и удобства поддержки, если у вас есть 2 переменные, которые должны иметь одинаковое значение, например RSи RFS, не устанавливайте для них по отдельности одно и то же значение, например RS="\""; RFS="\"", либо устанавливайте для них это значение вместе, например , RS=RFS="\""либо устанавливайте для одной из них значение другой, например RS="\""; RFS=RS.

Вот как правильно написать код в вашем вопросе:

$ 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

Чтобы сделать что-то еще с CSV с помощью awk, см.какой-самый-надежный-способ-эффективно-разобрать-csv-с-помощью-awk.

решение2

Ошибка, которую вы получаете, возникает из-за использования конкатенации значения RFS(пустой переменной) и $0в качестве строки формата с printf.

Ваш файл является допустимым CSV-файлом, за исключением пробелов после некоторых разделительных запятых (что портит цитирование поля Address; цитируемое поле должно иметь начальный символ кавычек сразу после разделителя). Мы можем исправить это с помощью csvformat(часть csvkit изhttps://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

База данных, способная анализировать CSV, должна иметь возможность прочитать эти данные как есть.

Если вы по-прежнему хотите заменить все встроенные запятые на |, просто измените разделитель файла на что-то другое, нежели запятая (ниже я буду использовать табуляцию), замените все оставшиеся запятые на вертикальные линии и снова вернитесь к использованию запятых в качестве разделителей.

Мы можем сделать это непосредственно с исходными данными:

$ 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

Короткие варианты различных длинных опций: -Sfor --skipinitialspace, -Tfor --out-tabsи -tfor --tabs.

Связанный контент