2015-06-15 2 views
-2

У меня есть большой набор данных с 586696 строк и 40 столбцов. Однако меня интересуют только некоторые из этих столбцов. В нем есть имена, а у других есть номера.Регулярное выражение как разделитель полей в awk

Мне очень трудно иметь дело с разделителями полей в этом файле. Все разделители столбцов - это пробелы. Если вы полагаете, что мой файл называется test.txt и имеет 5 человек в нем, это выглядит следующим образом:

Name Salary 
FirstName01 LastName01 Salary01 
FirstName02 MiddleName02 LastName02 Salary02 
FirstName03 MiddleName03 LastName03 Salary03 
FirstName04 LastName04 Salary04 
FirstName05 MiddleName05 LastName05 Salary05 

Следовательно, если я бегу

awk '{print $1 " " $2}' test.txt 

результат

Name Salary 
FirstName01 LastName01 
FirstName02 MiddleName02 
FirstName03 MiddleName03 
FirstName04 LastName04 
FirstName05 MiddleName05 

, но я хочу, чтобы это было

Name Salary 
FirstName01 LastName01 Salary01 
FirstName02 MiddleName02 LastName02 Salary02 
FirstName03 MiddleName03 LastName03 Salary03 
FirstName04 LastName04 Salary04 
FirstName05 MiddleName05 LastName05 Salary05 

Для решения этой проблемы предположим, что перед столбцом Name имеются столбцы и столбцы Salary.

Как я могу решить свою проблему? Думаю, мне нужно использовать какое-то регулярное выражение в качестве разделителя полей для использования awk здесь, но я не мог найти способ сделать это.

Редактировать: Я думаю, что я не был чист в исходном посте. Я знаю, что awk дает мне именно то, что я прошу. Моя проблема заключается в том, что мой полный набор данных что-то вроде

Column01 Column02 Column03 Name Salary Column06 ... 
Text0101 Text0102 Text0103 FirstName01 LastName01 Salary01 ... 
Text0201 Text0202 Text0203 FirstName02 MiddleName02 LastName02 Salary02 ... 
Text0301 Text0302 Text0303 FirstName03 MiddleName03 LastName03 Salary03 ... 
Text0401 Text0402 Text0403 FirstName04 LastName04 Salary04 ... 
Text0501 Text0502 Text0503 FirstName05 MiddleName05 LastName05 Salary05 ... 

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

Name Salary 
FirstName01 LastName01 Salary01 
FirstName02 MiddleName02 LastName02 Salary02 
FirstName03 MiddleName03 LastName03 Salary03 
FirstName04 LastName04 Salary04 
FirstName05 MiddleName05 LastName05 Salary05 

Sorry о моем недостоверной вопрос.

+1

AWK является делая то, что вы сказали ему, я t разбивается на пространство (по умолчанию), затем печатает слово 1, разделенное пробелом, затем слово2. Почему вы хотите воспроизвести результат? По крайней мере, я не вижу разницы во вводе и выходе, и awk, который вы пытаетесь сделать, кажется излишним. – melwil

+1

Как вы хотите отличаться от оригинала? – 123

+0

Вам нужно сохранить пустую строку в столбце среднего имени, если нет среднего имени, так что вы можете однозначно указать, в каком столбце содержится фамилия. – chepner

ответ

0

Согласно комментарию @jas: вы можете проверить количество столбцов с переменной NF в awk. Так что-то вроде этого следует сделать трюк для test.txt

awk '{name=$4; for (i = 5; i <= NF - 2; i++) name=name " " $i; salary=$i; print name " " salary}' test.txt 

Это печатает имя (начиная со столбцом 4) и добавляет каждый столбец вплоть до третьего последнего имени. Вторая вторая колонка будет тогда зарплатой.

Конечно, вы должны отрегулировать значения в 'name = $ 4', 'i = 5' и 'NF - 2' для ваших нужд.

Как другие указывают, было бы лучше изменить алгоритм, генерирующий набор данных таким образом, чтобы вы получили уникальный разделитель полей.

0

Ваша проблема в неправильном исходном формате! Если Name является единственным столбцом, расширяющимся на несколько полей, вы можете проверить количество полей в каждой строке и изменить выбор столбца.

awk 'NR==1{c=NF} {t=$4; for(i=5;i<6+(NF-c);i++) t=t " " $i; print t}' badformat.txt 
0

Если ни один из ваших «колонки» содержат пробелы и всегда есть такое же количество «столбцов» в каждой строке, то способ приблизиться к этому, чтобы начать в поле X и печати полей в (NF-Y). Таким образом, не имеет значения, сколько полей содержится в каждом «столбце» имени, так как конечная точка определяется тем, сколько столбцов должно оставаться после имени.

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

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

$ awk '{e=NF-1; for (i=4;i<=e;i++) printf "%s%s", $i, (i<e?OFS:ORS)}' file 
Name Salary 
FirstName01 LastName01 Salary01 
FirstName02 MiddleName02 LastName02 Salary02 
FirstName03 MiddleName03 LastName03 Salary03 
FirstName04 LastName04 Salary04 
FirstName05 MiddleName05 LastName05 Salary05 

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

$ cat file 
Column01 Column02 Column03 Name Salary ... 
Text0101 Text0102 Text0103 FirstName01 LastName01 Salary01 ... 
Text0201 Text0202 Text0203 FirstName02 MiddleName02 LastName02 Salary02 ... 
Text0301 Text0302 Text0303 FirstName03 MiddleName03 LastName03 Salary03 ... 
Text0401 Text0402 Text0403 FirstName04 LastName04 Salary04 ... 
Text0501 Text0502 Text0503 FirstName05 MiddleName05 LastName05 Salary05 ... 
Смежные вопросы