2015-10-22 4 views
2

Предположим, у меня есть набор данных с именами и регистров, какSplit данные, разделенные пробелами

John Wayne 1234 
Paul Newman 2345 Wrong register. The correct register is 2233 
John Fitzgerald Kennedy 3456 
Marilyn Monroe 1212 

Все линии разделены пространством. Я хочу, чтобы один (или два) регулярные выражения для использования в AWK, которые дают мне следующие результаты:

John Wayne 
Paul Newman 
John Fitzgerald Kennedy 
Marilyn Monroe 

и

1234 
2233 
3456 
1212 

Я знаю, что данные находятся в очень, очень плохое форматирование, но делает кто-нибудь знает, как мне помочь?

+1

Вы хотите иметь один скрипт awk для генерации двух выходов? или допустимо иметь две команды/сценарии для генерации двух выходов отдельно? – Kent

+0

Допустимо иметь два сценария. –

ответ

2

grep может быть использован для создания двух выходов в отдельности. Смотрите ниже тест:

$ cat f 
John Wayne 1234 
Paul Newman 2345 Wrong register. The correct register is 2233 
John Fitzgerald Kennedy 3456 
Marilyn Monroe 1212 

Выход I:

$ grep -o '^[^0-9]\+' f           
John Wayne 
Paul Newman 
John Fitzgerald Kennedy 
Marilyn Monroe 

Выходной II:

$ grep -o '[0-9]\+$' f 
1234 
2233 
3456 
1212 

В regexs, используемые выше, являются относительно простыми. Используя ту же идею, вы можете применить регулярное выражение с sed или awk, если хотите.

+0

Приятно, но первая команда 'grep' оставляет конечное пространство на каждой выходной строке. – mklement0

1

Этот случай достаточно прост, так как цифры после последнего сепаратора, поэтому мы будем рассматривать последний столбец, как если бы мы не знали о его содержании, как это:

awk '{print $NF}' 

В остальном мы» буду просто соответствовать всем буквам, включая пробела, пока не дойдут до небуквенного характера (например, номер), а затем мы просто заменить все остальное с нулем:

sed 's/\([A-z ]*\) .*/\1/g' 
+1

Претензии к умному, прагматичному решению 'awk', но ваша команда' sed' оставляет конечное пространство; вы можете добавить вторую команду внутри скрипта 'sed' для исправления:'; s/$ // ' – mklement0

+0

Теперь лучше? – Yaron

+1

Да, отлично (++) - лучше, чем мое предложение. – mklement0

0

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

awk -F"[0-9]" '{print $1}' /tmp/x 
+0

Приятно, но вы отвечаете только на половину вопроса (вы извлекаете только имена, а не цифры). '-F" [0-9] "' (by '' Я имею в виду фактический пробел.) Удалит конечные пробелы из вывода. – mklement0

1

Вы можете использовать sed:

sed 's/[[:blank:]]*[[:digit:]]\+.*$//' file 
John Wayne 
Paul Newman 
John Fitzgerald Kennedy 
Marilyn Monroe 

sed 's/.*[[:blank:]]\([[:digit:]]\+\)$/\1/' file 
1234 
2233 
3456 
1212 
1

Late к партии, но это позволяет делать оба дела сразу:

#!/usr/bin/awk -f 

    { 
     nums = nums "\n" $NF 
     split($0, a, " [0-9]{4}") 
     names = names a[1] "\n" 
    } 

END { 
     print names nums 
    } 

Во-первых, это занимает последнее поле линии и добавляет это список номеров. Затем он разбивает строку на любое 4-значное число и добавляет часть до разделения в список имен. Наконец, он печатает список имен, за которыми следует список номеров.

Выход:

John Wayne 
Paul Newman 
John Fitzgerald Kennedy 
Marilyn Monroe 

1234 
2233 
3456 
1212 

Если постороннее пространство беспокойства, труба к cat -e, чтобы сделать это очень ясно, где пробела могут иметь место.

+0

Хорошо сделано, но вы должны использовать '" [0-9] {4} "' (обратите внимание на ведущее пространство), чтобы исключить конечное пространство после имен. Кроме того, '{print names nums}' (без запятой) избежит одиночного пробела в разделительной строке. Возможно, вы можете переформатировать команду 'awk', чтобы быть многострочной для удобочитаемости, и предоставить образец вывода. – mklement0

+0

Хорошие предложения. Благодарю. – Andrew

+0

Спасибо за обновление, ++; обратите внимание, что POSIX-подобные оболочки, такие как 'bash', поддерживают многострочные строковые литералы, поэтому сохранение формы _CLI_ решения _combined с многострочной строкой_ предлагает лучшее из обоих миров: читаемость, при этом все еще можно вставлять команду в терминал для быстрого тестирования; см. [здесь] (http://stackoverflow.com/a/33271539/45375) для примера. – mklement0