как сделать первую строку в качестве заголовка в текстовом файле с помощью awk - PullRequest
0 голосов
/ 15 сентября 2018

ввод в виде CSV-файла показан ниже

name,id no,marks in cc  
xyzc,10000,56   
ABCb,10001,75   
xyza,10000,56  
xyz1,10000,56  

Ожидаемый вывод выглядит следующим образом, т.е. текстовый файл, в котором разделитель также заменен с ',' на '^', и после добавления пунктирной строки 1.

name ^ id no ^ marks in cc  
...........................
xyzc ^ 10000 ^ 56   
ABCb ^ 10001 ^ 75   
xyza ^ 10000 ^ 56  
xyz1 ^ 10000 ^ 56      

как я могу сделать такие договоренности в awk, может кто-нибудь, пожалуйста, помогите решить эту проблему

Ответы [ 5 ]

0 голосов
/ 16 сентября 2018

Ах, еще один конкурс. : - /

Мне нравится пока лучшее решение от sedong. Но вот супер маленькое решение awk:

awk -F, '$1=$1;NR==1&&gsub(/./,".")' OFS=" ^ " file.csv

Вот что мы делаем:

  • -F, - устанавливает разделитель поля ввода на ,.
  • $1=$1 - устанавливает первое поле в первое поле. Это (1) переписывает строку, чтобы заменить FS на OFS, а (2) всегда должно вычисляться до true, тем самым печатая строку. Это приводит к печати каждой строки с заменой разделителей входных полей на разделители выходных полей.
  • NR==1&&gsub(...) - печатает пунктирную линию, заменяя все остальные символы точкой, если мы все еще на первой строке.
  • OFS=" ^ " - устанавливает разделитель выходного поля.

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

Обычно сценарии awk считаются состоящими из condition { statement } пар, но вы заметите, что в этом сценарии awk нет фигурных скобок. Пропущенный { statement } считается {print}. Таким образом, сценарий состоит из двух пар с пропущенными операторами: первая вычисляется для каждой строки, а вторая - только для первой и используется для создания пунктирной линии.

0 голосов
/ 15 сентября 2018

Это может сработать для вас (GNU sed):

sed 's/,/ ^ /g;1p;1s/././g' file

Заменить все , на ^. Напечатайте первую строку и затем замените первую строку на ..

0 голосов
/ 15 сентября 2018

Небольшая альтернатива, но по сути та же самая

awk '{gsub(/,/," ^ ")}1;(NR==1){gsub(/./,".")}(NR==1)'  file

Этот код по существу делает следующее:

  1. читает строку и сохраняет ее в $0 (этопо умолчанию, код для этого не написан)
  2. {gsub(/,/," ^ ")}: заменить все , на строку " ^ " и сохраните все в $0
  3. 1: это сокращение, эквивалентное {print $0}, поэтому выведите строку $0
  4. (NR==1){action}: Если номер записи / строки NR равен 1, выполнить action, где action равно
    1. {gsub(/./,".")}: заменить всесимволы . .Это создает ваше подчеркивание
  5. (NR==1): , что эквивалентно (NR==1)1, что эквивалентно (NR==1){print $0}, который указывает, равен ли номер записи / строкик одному снова напечатайте $0, который теперь является строкой точек.
  6. Вернитесь к 1

Примечание: баллов 4 и 5 могли бы быть объединены как (NR==1){gsub(/./,".");print $0}

Другое решение:

awk '{$1=$1}1;(NR==1){gsub(/./,".")}(NR==1)'  FS=, OFS=" ^ " file

Этот код по существу выполняет следующее:

  1. FS=, OFS=" ^ ": Установите разделитель полей на , , а выходной разделитель полей - на строку " ^ "
  2. прочитать строку и сохранить ее в $0 (это значение по умолчанию, для этого не написан код)
  3. {$1=$1}: перестроить $0 с помощьюзамена всех FS на OFS.По сути, это эквивалентно awk '{gsub(/,/," ^ ")} в первом случае.
  4. 1: это сокращение, эквивалентное {print $0}, поэтому выведите строку $0
  5. (NR==1){action}: Если номер записи / строки NR равен 1, выполните action, где action равно
    1. {gsub(/./,".")}: заменить все символы на . .Это создает ваше подчеркивание
  6. (NR==1): это эквивалентно (NR==1)1, что эквивалентно (NR==1){print $0}, который указывает, равен ли номер записи / строкик одному снова напечатайте $0, который теперь является строкой точек.
  7. Вернитесь к 2

Это значение может быть сокращено до

awk '($1=$1);(NR==1) && gsub(/./,".")'  FS=, OFS=" ^ " file

но это становится более загадочным и не читаемым, и даже вводит крошечную возможность для ошибки (см. Комментарий Эда Мортона ниже этого поста)и легче всего отлаживать.

0 голосов
/ 15 сентября 2018
$ awk -F',' -v OFS=' ^ ' '{$1=$1; print} NR==1{gsub(/./,"."); print}' file
name ^ id no ^ marks in cc
..........................
xyzc ^ 10000 ^ 56
ABCb ^ 10001 ^ 75
xyza ^ 10000 ^ 56
xyz1 ^ 10000 ^ 56

Как правило, когда у вас еще нет строки для преобразования в некоторое повторение символов, для печати строки символов (или строк!) Определенной длины N вы используете str=sprintf("%*s",N,""), а затем заменяете каждый пробел char на выходе с символом (или строкой) C, который вы хотите напечатать, используя gsub(/ /,"C",str).

$ awk -F',' -v OFS=' ^ ' '{$1=$1; print} NR==1{dots=sprintf("%*s",length($0),""); gsub(/ /,".",dots); print dots}' file
name ^ id no ^ marks in cc
..........................
xyzc ^ 10000 ^ 56
ABCb ^ 10001 ^ 75
xyza ^ 10000 ^ 56
xyz1 ^ 10000 ^ 56
0 голосов
/ 15 сентября 2018
{
    gsub(",", " ^ ");
    print;
    if (NR == 1) {
        gsub(/./, ".");
        print;
    }
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...