Рассматривайте две колонки как одну - PullRequest
4 голосов
/ 16 апреля 2020

Образец текста:

$ cat X
Birth Death Name
02/28/42 07/03/69 Brian Jones
11/27/42 09/18/70 Jimi Hendrix
11/19/43 10/04/70 Janis Joplin
12/08/43 07/03/71 Jim Morrison
11/20/46 10/29/71 Duane Allman

После обработки с помощью Perl, column & sed:

$ perl -lae 'print "$F[2]_$F[3] $F[0]"' X | column -t | sed 's/_/ /g'
Name          Birth
Brian Jones   02/28/42
Jimi Hendrix  11/27/42
Janis Joplin  11/19/43
Jim Morrison  12/08/43
Duane Allman  11/20/46

Это именно тот вывод, который мне нужен. Но проблема в том, что я не хочу использовать column -t | sed 's/_/ /g' в конце.

Моя интуиция заключается в том, что это можно сделать только с помощью perl oneliner (без необходимости использования sed или column).

Возможно ли это? Как я могу это сделать?

PS У меня также есть решение awk (awk '{print $3"_"$4" "$1}' X | column -t | sed 's/_/ /g') для того же результата. Однако я ищу решение perl only.

Ответы [ 2 ]

5 голосов
/ 16 апреля 2020

В одну сторону

perl -wlnE'say join " ", (split " ", $_, 3)[-1,0]' input.txt

Это ограничивает split тремя терминами - сначала два поля, полученные обычным расщеплением по заданному шаблону, а затем остальные, здесь содержащие имя .

Он не будет правильно выстраиваться, как в показанном выводе.


Если правильное выравнивание является обязательным, то есть еще что сделать, так как сначала нужно увидеть весь файл чтобы знать, какой должна быть ширина поля. Тогда «one» -liner (программа командной строки) будет

perl -MList::Util=max -wlne'
    push @recs, [ (split " ", $_, 3)[-1,0] ];
    END { 
        $m = max map { length $_->[0] } @recs; 
        printf("%-${m}s %s\n", @$_) for @recs
    }' input.txt

Если допустима ширина поля, заданная априори, как указано в комментарии, мы можем сделать

perl -wlne'printf "%-20s %s\n", (split " ", $_, 3)[-1,0]' input.txt

Спасительная благодать для очевидного недопущения сюда - что с именами, которые длиннее? - это то, что только те конкретные строки будут не в порядке.

1 голос
/ 16 апреля 2020

Посмотрите, будет ли следующий лайнер приемлемым решением

perl -ne "/(\S+)\s+\S+\s+(.*)/, printf \"%-13s %s\n\",$2,$1" birth_data.dat

Вход birth_data.dat

Birth Death Name
02/28/42 07/03/69 Brian Jones
11/27/42 09/18/70 Jimi Hendrix
11/19/43 10/04/70 Janis Joplin
12/08/43 07/03/71 Jim Morrison
11/20/46 10/29/71 Duane Allman

Выход

Name          Birth
Brian Jones   02/28/42
Jimi Hendrix  11/27/42
Janis Joplin  11/19/43
Jim Morrison  12/08/43
Duane Allman  11/20/46
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...