Переформатирование таблиц

У меня есть следующий тип таблиц:

ID   date     DailyFlow
a 1972-01-01 17.0265761797993
b 1972-01-02 17.200476457399
c 1972-01-03 17.2926436045271
d 1972-01-04 17.3900277599829
e 1972-01-05 17.5987080931028
f 1972-01-06 17.6334881486229
g 1972-01-07 17.7030482596626
...

Я хотел бы переформатировать их следующим образом:

YYYY    DDD sim
1972    1   17.0265761797993
1972    2   17.200476457399
1972    3   17.2926436045271
1972    4   17.3900277599829
1972    5   17.5987080931028
1972    6   17.6334881486229
1972    7   17.7030482596626
1972    8   17.7204382874227

Первая строка содержится в таблицах. Файлы представляют собой обычный текст (* .txt) с разделителем «табуляция». Столбец ID - фиктивная, от которой я бы хотел избавиться! В моем желаемом выводе числа (1,2,3, ...) в столбце DDD должны совпадать с днем ​​соответствующих лет.

Есть ли у кого-нибудь идеи о том, как это сделать (используя bash)? Спасибо!

2
задан 14 August 2015 в 15:36

4 ответа

Используя awk для парсинга и date отформатировать дату, что еще ;)

awk 'BEGIN {printf "%s\t%s\t%s\n","YYYY","DDD","sim"} NR != 1 {system("date -d \""$2"\" +\"%Y\t%-d\t"$3"\"")}' your_file

Показать день года (использование %j вместо %d или лучше %-j вместо %-d, - старается не вести 0)

awk 'BEGIN {printf "%s\t%s\t%s\n","YYYY","DDD","sim"} NR != 1 {system("date -d \""$2"\" +\"%Y\t%-j\t"$3"\"")}' your_file

Пример

Входной файл

% cat foo
ID   date     DailyFlow
a 1972-01-01 17.0265761797993
b 1972-01-02 17.200476457399
c 1972-01-03 17.2926436045271
d 1972-01-04 17.3900277599829
e 1972-01-05 17.5987080931028
f 1972-01-06 17.6334881486229
g 1972-01-07 17.7030482596626
h 1972-02-01 17.7030482596626
i 1972-02-02 17.7030482596626

Вывод (со днем месяца)

% awk 'BEGIN {printf "%s\t%s\t%s\n","YYYY","DDD","sim"} NR != 1 {system("date -d \""$2"\" +\"%Y\t%-d\t"$3"\"")}' foo
YYYY    DDD sim
1972    1   17.0265761797993
1972    2   17.200476457399
1972    3   17.2926436045271
1972    4   17.3900277599829
1972    5   17.5987080931028
1972    6   17.6334881486229
1972    7   17.7030482596626
1972    1   17.7030482596626
1972    2   17.7030482596626

Вывод (со днем года)

% awk 'BEGIN {printf "%s\t%s\t%s\n","YYYY","DDD","sim"} NR != 1 {system("date -d \""$2"\" +\"%Y\t%-j\t"$3"\"")}' foo
YYYY    DDD sim
1972    1   17.0265761797993
1972    2   17.200476457399
1972    3   17.2926436045271
1972    4   17.3900277599829
1972    5   17.5987080931028
1972    6   17.6334881486229
1972    7   17.7030482596626
1972    32  17.7030482596626
1972    33  17.7030482596626
2
ответ дан 15 August 2015 в 01:36
  • 1
    Спасибо @Mladen. Первая точка (никакой " тихий splash" и добавление " nomodeset") точно, что я делал для вхождения в систему. – DrAl 8 November 2016 в 23:02

Используйте awk:

awk 'BEGIN{print "YYYY\tDDD\tsim"} NR!=1{printf "%s\t%s\t%s\n",substr($2,0,5),$1,$3}' file

Объяснение

  1. BEGIN{} часть форматирует строку заголовка.
  2. NR!=1 опускает строку заголовка Ваших форматов файла
  3. printf(), вывод
  4. substr($2,0,5) удаляет день и месяц с даты

выходные взгляды:

YYYY    DDD     sim
1972    1       17.0265761797993
1972    2       17.200476457399
1972    3       17.2926436045271
1972    4       17.3900277599829
1972    5       17.5987080931028
1972    6       17.6334881486229
1972    7       17.7030482596626
1
ответ дан 15 August 2015 в 01:36
  • 1
    @DrAl Don' t честное слово, поскольку экспертные знания, начиная со всего, что я пишу, являются " selftaught" канавка Интернет, поэтому что I' m запись могло бы также быть неправильным - но здесь мы идем. Я думаю, что проблема, возможно, была решена для других (более старых) CPU, но я знаю, что у меня были проблемы с skylake даже с " зафиксированный issues" примечание по ядрам Linux, по крайней мере, для тех, которых использует человечность. Когда я сначала установил человечность, и она наконец работала, некоторый микропрограммный материал не контролировался. Например, вентиляторы ушли в полной скорости после ~2min после начальной загрузки, некоторые функциональные ключи (свет, авиарежим) все еще don' t работают правильно. – lemdan 9 November 2016 в 00:29

Используя только bash:

#!/bin/bash
shopt -s extglob
printf "YYYY\tDDD\tsim\n"
while IFS= 
  • Мы читаем каждую строку входного файла, начинающего со второй строки, и помещающий вкладку разделил части как переменную first, second, и third последовательно

  • Затем мы используем bash расширение параметра для получения нашего желаемого выходного шаблона. Читайте о расширении параметра от , документ .

  • extglob GNU используется для удаления заполненного, обнуляет со дней.

Пример:

Вход:

ID  date        DailyFlow
a   1972-01-01  17.0265761797993
b   1972-01-02  17.200476457399
c   1972-01-03  17.2926436045271
d   1972-01-04  17.3900277599829
e   1972-01-05  17.5987080931028
f   1972-01-06  17.6334881486229
g   1972-01-07  17.7030482596626
h   1972-02-01  17.7030482596626
i   1972-02-02  17.7030482596626

Вывод:

YYYY    DDD   sim
1972    1     17.0265761797993
1972    2     17.200476457399
1972    3     17.2926436045271
1972    4     17.3900277599829
1972    5     17.5987080931028
1972    6     17.6334881486229
1972    7     17.7030482596626
1972    32    17.7030482596626
1972    33    17.7030482596626
\t' read -r first second third; do day="$(date --date="$second" '+%j')" printf "%s\t%s\t%s\n" "${second%%-*}" "${day##*(0)}" "${third}" done < <(tail -n +2 foo.txt)
  • Мы читаем каждую строку входного файла, начинающего со второй строки, и помещающий вкладку разделил части как переменную first, second, и third последовательно

  • Затем мы используем bash расширение параметра для получения нашего желаемого выходного шаблона. Читайте о расширении параметра от , документ .

  • extglob GNU используется для удаления заполненного, обнуляет со дней.

Пример:

Вход:

ID  date        DailyFlow
a   1972-01-01  17.0265761797993
b   1972-01-02  17.200476457399
c   1972-01-03  17.2926436045271
d   1972-01-04  17.3900277599829
e   1972-01-05  17.5987080931028
f   1972-01-06  17.6334881486229
g   1972-01-07  17.7030482596626
h   1972-02-01  17.7030482596626
i   1972-02-02  17.7030482596626

Вывод:

YYYY    DDD   sim
1972    1     17.0265761797993
1972    2     17.200476457399
1972    3     17.2926436045271
1972    4     17.3900277599829
1972    5     17.5987080931028
1972    6     17.6334881486229
1972    7     17.7030482596626
1972    32    17.7030482596626
1972    33    17.7030482596626
1
ответ дан 15 August 2015 в 01:36
  • 1
    @DrAl, Что решило самые критические проблемы для меня, устанавливал собственные драйверы (Intel, Nvidia) и устанавливал последнее ядро Linux. – lemdan 9 November 2016 в 00:39

This был бы заданием для awk, но замена во втором столбце потребует gensub и следовательно gawk, который не установлен по умолчанию, таким образом я закончил с sed решение:

sed -i.bak 's/[^\t]*\t\([^-]*\)-[0-9][0-9]-[0-9]\([0-9]\)[^\t]*\t\([^\t]*\)/\1\t\2\t\3/' infile

Или, сокращенное использование EREs (благодаря user1598390):

sed -E -i.bak 's/.*([0-9]{4})-[0-9]{2}-([0-9]{2})(.*)/\1\t\2\3/' infile
  • -i.bak: обрабатывает файл на месте, создавая резервную копию исходного файла к infile.bak

sed разбивка команды:

  • s: утверждает для выполнения замены;
  • /: запускает шаблон
  • [^\t]*: соответствия любое количество любого символа не \t;
  • \t: соответствует \t символ
  • \(: запускает первую группу фиксации
  • [^-]*: соответствия любое количество любого символа не -;
  • \): останавливает первую группу фиксации
  • -: соответствует - символ
  • [0-9]: соответствия любая цифра
  • [0-9]: соответствия любая цифра
  • -: соответствует - символ
  • [0-9]: соответствия любая цифра
  • \(: запускает вторую группу фиксации
  • [0-9]: соответствия любая цифра
  • \): останавливает вторую группу фиксации
  • [^\t]*: соответствия любое количество любого символа не \t;
  • \t: соответствует \t символ
  • \(: запускает третью группу фиксации
  • [^\t]*: соответствия любое количество любого символа не \t;
  • \): останавливает третью группу фиксации
  • /: останавливается шаблон / запускает замещающую строку
  • \1: обратная ссылка заменяется первой группой фиксации
  • \2: обратная ссылка заменяется второй группой фиксации
  • \3: обратная ссылка заменяется третьей группой фиксации
  • /: останавливается замещающая строка / запускает модификаторы

Вывод для файла примера:

user@debian ~/tmp % cat infile 
a   1972-01-01  17.0265761797993
b   1972-01-02  17.200476457399
c   1972-01-03  17.2926436045271
d   1972-01-04  17.3900277599829
e   1972-01-05  17.5987080931028
f   1972-01-06  17.6334881486229
g   1972-01-07  17.7030482596626
user@debian ~/tmp % sed 's/[^\t]*\t\([^-]*\)-[0-9][0-9]-[0-9]\([0-9]\)[^\t]*\t\([^\t]*\)/\1\t\2\t\3/' infile
1972    1   17.0265761797993
1972    2   17.200476457399
1972    3   17.2926436045271
1972    4   17.3900277599829
1972    5   17.5987080931028
1972    6   17.6334881486229
1972    7   17.7030482596626
7
ответ дан 15 August 2015 в 01:36
  • 1
    Извините - утверждал, что комментарий, прежде чем я значил для... Я попробовал графические драйверы Intel (неудачно), когда я первоначально установил 16.04; я can' t помнят, каким ядром это было с, таким образом, I' попытка ll, что снова на 16,10 в случае, если это имеет значение. I' ll делают попытку с 4.8.6 и сообщат; учитывая, что эта проблема была предположительно устранена в 4,3, это кажется оптимистичным. I' ve изо всех сил пытался найти какую-либо информацию о версии, которая покажет различия между 4,8 и 4.8.6, чтобы видеть, существует ли кто-либо соответствующие меры - Вы знаете, где я мог бы найти их? – DrAl 8 November 2016 в 23:05

Другие вопросы по тегам:

Похожие вопросы: