Как записать файл в массив awk

Обновлено: 07.07.2024

Мне нужно проанализировать файл csv и выгрузить его содержимое в таблицы mysql.

Во втором выводе мне нужно, чтобы пользовательские заголовки были выровнены по горизонтали. Например,

Для второго вывода это может быть любой набор заголовков, который я выберу. Затем я могу загрузить оба этих выходных данных в таблицы mysql, используя файл данных загрузки. Ищу сценарии awk для этого. Позвольте мне знать, если вам нужно что-нибудь еще. Tx.

2 ответа

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

Вышеупомянутое использует GNU awk для FPAT , с другими awk вам понадобится цикл while(match(. )) .

  1. Первый sub() и тест на NF отбрасывают комментарии и пустые строки.
  2. gsub() перед циклом заменяет каждое вхождение \" новой строкой, так что экранированные кавычки не мешают разделению полей, а тот факт, что эта операция работает со всей записью, заставляет awk заново затем разделите, так что FPAT снова применяется в этой точке, гарантируя, что исходные \" не влияют на поля, входящие в цикл.
  3. gsub() в 1-м цикле восстанавливает все \" , которые изначально присутствовали в текущем поле.
  4. Первый gsub() во втором цикле просто обрезает все начальные и конечные пробелы в текущем поле.
  5. Второй [необязательный] gsub() во втором цикле удаляет начальные / конечные кавычки из поля.

А остальное должно быть очевидно. Я удаляю начальные / конечные пробелы и кавычки, где используется f[] , а не там, где он заполняется, поскольку вам, кажется, нужно как минимум 2 разных вывода, один с окружающими кавычками и один без, но это ваш выбор, где любой из этих gsub() готово.

Чтобы изучить awk, возьмите книгу Арнольда Роббинса «Эффективное программирование на Awk», 4-е издание.

Это должно работать:

В основном он сохраняет первую строку в массиве header , затем split каждую строку в массиве elem и удаляет начальные и конечные пробелы или табуляции. Наконец, он составляет строку вывода.

Вы можете избавиться от новых строк между каждым блоком, удалив последний оператор print "" .

10.17. Массивы

awk поддерживает одномерные массивы. Массивы и элементы массивов нет необходимости объявлять. Индексы массива могут быть числом или строкой. Пример условного обозначения числового индекса:

присваивает текущую строку вводного файла элементу NR массива x.

Фактически возможно считать целый вводной файл в массив с помощью программы awk:

Первое действие только записывает каждую строку вводного файла, отмеченную номером строки, в массив x, обработка выполняется в операторе END.

Элементы массива могут именоваться с помощью нецифровых величин. Например, следующая программа накапливает общее количество населения Asia и Africa в соответветствующий массив pop. Оператор END печатает общее количество населения этих двух континентов.

Результат получим следующий:

Asian population in million is 1765
African population in million is 37

В этой программе, если вы воспользуетесь pop[Asia] вместо pop["Asia"], то выражение будет использовать значение переменной как индекса, и так как значение переменной не установлено, то количество населения будет накапливаться в pop[""].

Предположим, нужно определить общую площадь каждого континента из файла countries.

Каждое выражение может быть использовано как индекс при ссылке в массиве. Так:

использует строку в 4-м поле текущей записи вводного файла для индексирования массива area, накапливая значение второго поля:

Относительно файла countries получим результат:

Asia 13611
North America 7467
South America 4358
Australia 2968
Africa 1888

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

выполняется "оператор" с переменной i , для которой определен array(i). Цикл выполняется для каждого определенного индекса, который выбирается в произвольном порядке.

awk не поддерживает многомерные массивы, но допускает список индексов. Они объединяются в один индекс значениями, разделенными строкой (хранимой в переменной SUBSEP).

создает массив, который ведет себя как двумерный массив. Индексом является сочетание i, SUBSEP и j.

Вы можете определить, появляется ли конкретное i в массиве arr:

Это условие приведет к выполнению тестирования без создания массива ["Africa"]. Этот массив создался, бы если использовалось

Возможно также разбить любую строку на поля, которые станут элементами массива. Это можно сделать с помощью встроенной функции split:

split разбивает строку на 3 поля, используя в качестве разделителя ":" и сохраняя s1 в [1], s2 - в [2], s3 - в [3]. Возвращаемое значение этого оператора равно числу полей, т.е. трем. Третий аргумент функции split - это регулярное выражение, будет использоваться как поле разделителя. Если третий аргумент отсутствует, то в качестве поля разделителя будет использоваться FS.

Массив элементов может быть разделен с помощью аргумента delete:

10.18. Функции, определенные пользователем

awk поддерживает функции, определенные пользователем:

Это определение может появляться в любом месте, где возможен оператор "шаблон-действие". Список аргументов - это список имен переменных, разделенных запятыми. Внутри тела функции эти переменные ссылаются на действительные переменные при вызове функции. Между именем функции и левой круглой скобкой не должно быть пробела, иначе это будет означать конкатенацию.

Массив элементов просматривается при обращении, как и в Си. Функция при просмотре не может изменить значение скалярных аргументов. Внутри функции формальные параметры являются локальными переменными, но все другие переменные являются глобальными. У вас может быть любое количество формальных параметров, которые используются только как локальные переменные. Операторreturnявляется необязательным, но если он отсутствует, возвращаемое значение будет неопределенным.

10.19. Комментарии

AWK - утилита предназначенная для простых, механических и вычислительных манипуляций над данными. Довольно несложные операции часто необходимо выполнить над целыми пакетами файлов, а писать для этого программу на одном из стандартных языков программирования является утомительным и, как правило, не очень простым делом. Оптимальное решение проблемы - использование специальной утилиты AWK , включающей в себя не громоздкий и удобный язык программирования, позволяющий решать задачи обработки данных с помощью коротких программ, состоящих из двух-трех строк.

Утилита AWK изначально объединяла свойства утилит UNIX - sed и grep . В дальнейшем ее возможности значительно расширились. Настоящая документация ограничивается описанием возможностей утилиты AWK реализованной для компьютеров CONVEX . Утилита AWK была создана в 1977г, американскими авторами: Alfred V.Aho , Brian W.Kernighan и Peter J.Weinberger . Подробное описание всех возможностей утилиты AWK для UNIX дает их издание: ``The AWK Programming Language'', 1988.

AWK сканирует input (стандартный или указываемый набор файлов), и над строками, удовлетворяющими заданному образцу, выполняет указываемые действия. Строка может содержать максимально до 256 символов.

awk [-Fc] [-f file] [files]

awk [-Fc] [prog] [files]

prog - программа, вида: ' образец $$ '

file - файл с AWK-программой:

files - файлы, предназначенные для AWK-обработки.

-Fc - устанавливает разделитель полей в ``с'' (См. 1.2.1 и 2.4)

  • Полей;
  • Переменных (Стандартных, Массивов);
  • Арифметических выражений.
  • Регулярное выражение;
  • Выражение отношения;
  • Комбинация образцов;
  • BEGIN и END .
  • Последовательность предложений, разделенных `` ; '' или `` \n '' (новая строка)
  1. Вывод (Печать);
  2. Присваивание;
  3. Встроенная функция;
  4. Управляющая структура.
Каждая сканируемая строка input рассматривается как состоящая из полей, разделенных разделительными символами (по умолчанию - пробел).
  1. $1 - Первое поле;
  2. $2 - Второе поле;
  3. . и так далее.
  4. $0 - Ссылается на всю строку целиком.

Строка может содержать максимально до 100 полей.

< Drawing or tabular insertion skipped. >

Переменные могут интерпретироваться как числовые или строковые. Они принимают значения в зависимости от контекста, например:

x = 1 , x воспринимается как число;

x = " " , x - строка;

x + "abc" - результат операции интерпретируется как число независимо от того, было ли х числом или строкой. Если строка не может быть интерпретирована как число ( "abc" ), то ее значение становится 0.

Строка может содержать максимально до 256 символов.

Ссылки на поля $1 , $2 , . могут интерпретироваться в качестве переменных, например:

$1 = "3" + $2 - первое поле принимает значение второго поля, увеличенного на 3.

$(i+1) - интерпретируется как поле, номер которого зависит от значения переменной i .

Допускается использование массивов. Массивы не объявляются, а принимают значения из контекста, например:

x[NR] = $0 - элементу массива x , индексированному NR , присваивается обрабатываемая строка.

x["apple"] - элементы массива могут индексироваться не числовым значением, т.е. строкой.

  • Переменная;
  • Число;
  • Строка;
  • Встроенная функция;
  • Выражение < Операция > Выражение.
Для осуществление поиска в AWK языке допускается использование регулярных выражений, определенных в описании SED, (см. ``Неинтерактивный текстовый редактор SED'' 2.1), заключенных в`` / / ''. Дополнения к использованию регулярных выражений, допускаемые в AWK-языке:
  • "( )" - Скобки допускаются для группирования;
  • " |" - Указание альтернативы "или";
  • " + " - Плюс, стоящий за регулярным выражением означает любую последовательность вхождений этого выражения, начиная с 1;
  • " ? " - Знак вопроса за регулярным выражением означает 0 или 1 вхождений этого выражения;
  • [A-Z] - Допускается сокращенная форма записи для рангов ASCII символов;
  • Установленный порядок выполнения операторов на одном скобочном уровне: "[] * + ? конкатенация |" .

/Olga/ - Указывает на строки, содержащие Olga .

/[Oo]lga|[Mm]ike|[Mm]al/ - Указывает на строки, содержащие Olga или olga или Mike или mike или Mal или mal .

/number1/ - Указывает на строки, содержащие number0 или number1 или . number9 .

/\/.+\// - Указывает на строки, содержащие любое количество символов, больше или равное 1, заключенных в / / .

  • < Выражение > < Принадлежность > < Выражение >
  • < Выражение > < Лог. Операция > < Выражение >

Лог. Операция: < , < = , == , != , > = , > .

/[Oo]lga/ - Указывает на строки, первое поле которых содержит Olga или olga .

$1 > = "s" - Указывает на строки, начинающиеся с символа s или следующих за ним по порядку: t , u , v .

Допускается логическая комбинация образцов с использованием следующих знаков: || - ``или'', & & - ``и'', ! - ``не''.

Последовательности образцов, соединенных одним из знаков читаются слева направо.

Комбинация: ``образец1, образец2'' указывает, что действие выполняется над строками, попадающими в указанный ранг: то есть, начиная от строки, удовлетворяющей ``образец1" и вплоть до строки, удовлетворяющей ``образец2", включая ее саму.

/\.su/) - Указывает на строки, содержащие 02.95 и не имеющие .su одновременно в первом и во втором поле.

NR == 100, NR == 200 - Указывает строки с номерами от 100 до 200.

Образец BEGIN указывает на начало input или на те действия, которые должны быть выполнены до какого бы то ни было анализа строк. Образец END указывает на конец input или на те действия, которые должны быть выполнены после обработки всех строк.

BEGIN - Устанавливает разделитель полей в ":" до начала обработки строк. Эквивалентно опции "-F:" при AWK вызове.

END < print NR >- Печатает номер последней строки input , т.е. количество обработанных входных строк.

PRINT [< список выражений > ] [ > < выражение1 > ]

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

Значение < выражения1 > рассматривается как имя файла. Само его присутствие означает печать в файл. Если вместо `` > '' стоит `` > > '', то это означает добавление к уже существующему файлу. Можно использовать в одной программе максимально до 10 output файлов.

Оператор форматированной печати:

PRINTF формат [ ,список выражений ] [ > выражение1 ]

  • обычные символы, они копируются на output .
  • esc последовательности, представляющие неграфические символы, например, "\n" - новая строка.
  • спецификации для вывода аргументов, они следуют после символа `` % ''. Число спецификаций должно быть равно числу аргументов. (Если оно меньше числа аргументов, то лишние аргументы игнорируются, если же больше - то это ошибка)

< переменная > = < выражение >

length(arg) - Функция длины arg . Если arg не указан, то выдает длину текущей строки.

exp(),log(),sqrt() - Математические функции экспонента, логарифм и квадратный корень.

int() - Функция целой части числа.

substr(s,m,n) - Возвращает подстроку строки s , начиная с позиции m , всего n символов.

index(s,t) - Возвращает начальную позицию подстроки t в строке s . (Или 0, если t в s не содержится.)

sprintf(fmt,exp1,exp2. ) - Осуществляет форматированную печать (вывод) в строку, идентично PRINTF .

split(s,array,sep) - Помещает поля строки s в массив array и возвращает число заполненных элементов массива. Если указан sep , то при анализе строки он понимается как разделитель.

if ( < условие > ) < предложение >

\hskip 1cm [else < предложение > ]

while ( < условие > ) < предложение >

\hskip 1cm < предложение >

for(i=1; i< =NF; i++) - Аналогично циклу for в языке ``С''

for (i in array) - Цикл по элементам массива. Но, элементы массива доступны в этом случае в случайном порядке.

Пример-1: Определение и чтение одномерный массив в awk

Одномерный массив может хранить список данных одного столбца. Этот тип массива содержит один ключ и значение для каждого элемента массива. Этот массив можно использовать в команде awk, как и в других языках программирования. В этом примере массив с именем book объявлен с тремя элементами, а цикл for используется для чтения и печати каждого элемента. Выполните следующую команду из терминала.


Пример-2: Определение и чтение двумерного массива в awk

Двумерный массив используется для хранения списка табличных данных, содержащего фиксированное количество строк и столбцы. В этом примере объявлен двумерный массив с именем student, содержащий три элемента. Здесь идентификатор и имя студента используются как ключевые значения массива. Как и в предыдущем примере, в сценарии awk используется цикл for-in для печати значений массива. Запустите следующий сценарий из терминала.

Вывод:


Пример 3: Удаление элемента массива

Любое значение массива может быть удалено на основе значения ключа. Здесь в начале скрипта определен массив book с тремя элементами. Затем значение ключа HTML удаляется с помощью удалить . Значение элемента ключа HTML печатается до и после команды delete . Выполните следующую команду, чтобы проверить вывод.

Вывод:

Вывод показывает, что значение индекса HTML пусто после выполнения команды delete .


Пример 4: чтение массива bash в awk

В предыдущих примерах массив объявлен в команде awk и повторяется циклом for-in. Но вы можете прочитать любой массив bash с помощью сценария awk. В этом примере массив bash с именем lang объявлен в первой команде. Во второй команде значения массива bash передаются в команду awk, которая сохраняет все элементы в массиве awk с именем awkArray. Значения массива awkArray печатаются с использованием цикла for . Выполните следующую команду из терминала, чтобы проверить вывод.


Пример 5: Чтение содержимого файла в массив awk

Содержимое любого файла можно прочитать с помощью массива awk. Создайте текстовый файл с именем bird.txt с содержанием, указанным ниже.

bird.txt

Следующий скрипт awk используется для чтения содержимое файла bird.txt и сохраняет значения в массиве, цикл awkArray. for используется для анализа массива и печати значений в терминале. Запустите следующий сценарий из терминала.

Вывод:

Скрипт печатает содержимое bird .txt .


Пример 6: Удаление повторяющихся записей из файла

Сценарий awk можно использовать для удаления повторяющихся данных из любой текстовый файл. Создайте текстовый файл с именем fruit.txt со следующим содержанием. В файле есть два повторяющихся данных. Это Apple и Оранжевый .

fruit.txt

Apple
Апельсин
Виноград
Яблоко
Банан
Апельсин
Гуава

Следующий скрипт awk будет читать каждая строка из текстового файла, fruit.txt и проверьте, существует ли текущая строка в массиве, arr. Если строка существует в массиве, она не будет сохранять строку в массиве и не будет печатать значение в терминале. Таким образом, скрипт сохранит в массиве только уникальные строки из файла и распечатает. Выполните команды из терминала.

Первая напечатает содержимое файла, fruit.txt, а вторая команда напечатает содержимое из fruit.txt после исключения повторяющихся строк из файла.


Заключение:

В этом руководстве показаны различные варианты использования массива в сценарии awk на различных примерах с пояснениями. Доступ к массиву Bash и любому содержимому текстового файла также можно получить с помощью массива awk. Если вы новичок в программировании на awk, то это руководство поможет вам изучить использование массива awk на базовом уровне, и вы сможете правильно использовать массив в сценарии awk.

Читайте также: