Все задачи

Загадочная таблица-2

09 Oct 2013

Программисту достался еще один текстовый табличный файл (про первый была отдельная история).

> cat table2.txt
7.3 Connery 1962 1,100,000 16,067,035 43,500,000 59,600,000
7.5 Connery 1963 2,000,000 24,796,765 54,100,000 78,900,000
6.8 Lazenby 1969 7,000,000 22,774,493 59,200,000 87,400,000
6.7 Moore 1974 13,000,000 20,972,000 76,600,000 97,600,000
6.5 Dalton 1989 32,000,000 34,667,015 121,500,000 156,200,000
6.4 Brosnan 1997 110,000,000 125,332,007 221,300,000 333,011,068
6.7 Craig 2008 200,000,000 168,368,427 407,584,078 586,090,727

(таблицу можно скачать)

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

Получился такой однострочник:

> perl -ne '@a = split " "; shift @a; print join " ", @a;' table2.txt > result.txt

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

Подсказка

Показать

В файле result.txt оказалась всего одна строчка.

Подсказка-2

Показать

Правда, эта строчка – очень длинная.

Подсказка-3

Показать

> cat result.txt
Connery 1962 1,100,000 16,067,035 43,500,000 59,600,000Connery 1963 2,000,000 24
,796,765 54,100,000 78,900,000Lazenby 1969 7,000,000 22,774,493 59,200,000 87,40
0,000Moore 1974 13,000,000 20,972,000 76,600,000 97,600,000Dalton 1989 32,000,00
0 34,667,015 121,500,000 156,200,000Brosnan 1997 110,000,000 125,332,007 221,300
,000 333,011,068Craig 2008 200,000,000 168,368,427 407,584,078 586,090,727

Разоблачение

Показать

Дело в том, что split обрабатывает " " (строчку из одного пробела) в качестве первого параметра особым образом: в качестве разделителя рассматривается не одиночные пробелы, а последовательности “пробельных символов” (эквивалент регулярного выражения /\s+/). Перевод строки тоже является пробельным символом, так что после @a = split " "; последняя строка в @a не содержит перевода строки в конце.

Возможное решение – использовать в качестве разделителя / /:

> perl -ne '@a = split / /; shift @a; print join " ", @a;' table2.txt

Или добавить опцию -l, чтобы при печати каждой строки в ее конец добавлялся бы перевод строки:

> perl -lne '@a = split " "; shift @a; print join " ", @a;' table2.txt

Мы получили неожиданно много ответов от читателей, и самое полное и точное объяснение прислал Тигран tigran@