Разделить текстовый файл по его записям

Я пытаюсь проанализировать огромный текстовый файл (1,6 ГБ), чьи строки данных выглядят так:

20090118025859 -2.400000 78.100000 1023.200000 0.000000 20090118025900 -2.500000 78.100000 1023.200000 0.000000 20090118025901 -2.400000 78.100000 1023.200000 0.000000

Я даже не знаю, сколько строк есть. Но я пытаюсь разделить файл по дате. Левое число - это отметка времени (эти строки относятся к 2009 году, 18 января). [D1] Как я могу разбить этот файл на куски в соответствии с датой?

Все, что я знаю, будет grep file '20090118*' > data20090118.dat, но обязательно есть способ делать все даты сразу, правда?

Количество записей в день отличается, поэтому использование split с постоянным номером не будет работать.

Заранее спасибо, Alex

2
задан 2 March 2011 в 17:42

21 ответ

Возможно, это сработает для вас:

awk '{d=substr($1, 1, 8); fn = "data" d ".dat"; print $0 >> fn}' hugefile
1
ответ дан 25 July 2018 в 22:24

Предполагая, что файл отсортирован и даты всегда есть, это должно работать:

#!/bin/bash base_dir='./' while read line; do date="${line:0:8}" echo "$line" >> "$base_dir$date.txt" done < "$1"

[Сохранить как my_splitter, сделать его исполняемым, выполнив chmod +x my_splitter, а затем вызвать его как ./my_splitter input_file]

Он считывает входной файл по строкам, извлекает дату и использует это для добавления строк с той же датой к одному и тому же файлу.

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

6
ответ дан 25 July 2018 в 22:24
  • 1
    Вместо $(echo "$line" | cut -b 1-8) вы можете сделать ${line:0:8}, который короче и эффективнее. [D0] mywiki.wooledge.org/BashSheet#Parameter_Operations – geirha 3 March 2011 в 02:07
  • 2
    @geirha Спасибо, отредактирован. – htorque 3 March 2011 в 02:14

Я бы использовал {x..y}, возможно, для y, m, d cascading, shema:

for d in {18..19} ; do grep 200901$d datadata; echo; done 20090118025859 -2.400000 78.100000 1023.200000 0.000000 20090118025900 -2.500000 78.100000 1023.200000 0.000000 20090118025901 -2.400000 78.100000 1023.200000 0.000000 20090119025859 -2.400000 78.100000 1023.200000 0.000000 20090119025900 -2.500000 78.100000 1023.200000 0.000000 20090119025901 -2.400000 78.100000 1023.200000 0.000000
0
ответ дан 25 July 2018 в 22:24

Возможно, это сработает для вас:

awk '{d=substr($1, 1, 8); fn = "data" d ".dat"; print $0 >> fn}' hugefile
1
ответ дан 2 August 2018 в 03:51

Предполагая, что файл отсортирован и даты всегда есть, это должно работать:

#!/bin/bash base_dir='./' while read line; do date="${line:0:8}" echo "$line" >> "$base_dir$date.txt" done < "$1"

[Сохранить как my_splitter, сделать его исполняемым, выполнив chmod +x my_splitter, а затем вызвать его как ./my_splitter input_file]

Он считывает входной файл по строкам, извлекает дату и использует это для добавления строк с той же датой к одному и тому же файлу.

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

6
ответ дан 2 August 2018 в 03:51
  • 1
    Вместо $(echo "$line" | cut -b 1-8) вы можете сделать ${line:0:8}, который короче и эффективнее. [D0] mywiki.wooledge.org/BashSheet#Parameter_Operations – geirha 3 March 2011 в 02:07
  • 2
    @geirha Спасибо, отредактирован. – htorque 3 March 2011 в 02:14

Я бы использовал {x..y}, возможно, для y, m, d cascading, shema:

for d in {18..19} ; do grep 200901$d datadata; echo; done 20090118025859 -2.400000 78.100000 1023.200000 0.000000 20090118025900 -2.500000 78.100000 1023.200000 0.000000 20090118025901 -2.400000 78.100000 1023.200000 0.000000 20090119025859 -2.400000 78.100000 1023.200000 0.000000 20090119025900 -2.500000 78.100000 1023.200000 0.000000 20090119025901 -2.400000 78.100000 1023.200000 0.000000
0
ответ дан 2 August 2018 в 03:51

Возможно, это сработает для вас:

awk '{d=substr($1, 1, 8); fn = "data" d ".dat"; print $0 >> fn}' hugefile
1
ответ дан 4 August 2018 в 19:55

Предполагая, что файл отсортирован и даты всегда есть, это должно работать:

#!/bin/bash base_dir='./' while read line; do date="${line:0:8}" echo "$line" >> "$base_dir$date.txt" done < "$1"

[Сохранить как my_splitter, сделать его исполняемым, выполнив chmod +x my_splitter, а затем вызвать его как ./my_splitter input_file]

Он считывает входной файл по строкам, извлекает дату и использует это для добавления строк с той же датой к одному и тому же файлу.

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

6
ответ дан 4 August 2018 в 19:55
  • 1
    Вместо $(echo "$line" | cut -b 1-8) вы можете сделать ${line:0:8}, который короче и эффективнее. [D0] mywiki.wooledge.org/BashSheet#Parameter_Operations – geirha 3 March 2011 в 02:07
  • 2
    @geirha Спасибо, отредактирован. – htorque 3 March 2011 в 02:14

Я бы использовал {x..y}, возможно, для y, m, d cascading, shema:

for d in {18..19} ; do grep 200901$d datadata; echo; done 20090118025859 -2.400000 78.100000 1023.200000 0.000000 20090118025900 -2.500000 78.100000 1023.200000 0.000000 20090118025901 -2.400000 78.100000 1023.200000 0.000000 20090119025859 -2.400000 78.100000 1023.200000 0.000000 20090119025900 -2.500000 78.100000 1023.200000 0.000000 20090119025901 -2.400000 78.100000 1023.200000 0.000000
0
ответ дан 4 August 2018 в 19:55

Предполагая, что файл отсортирован и даты всегда существуют, это должно работать:

  #! / bin / bash base_dir = '. /' во время чтения строки;  do date = "$ {line: 0: 8}" echo "$ line" & gt; & gt; & gt; & gt;  "$ base_dir $ date.txt" done & lt;  «$ 1»  

[Сохраните его как my_splitter , сделайте его выполнимым, запустив chmod + x my_splitter , затем назовите его как ./ my_splitter input_file ]

Он считывает входной файл по строкам, извлекает дату и использует это, чтобы добавить строки с той же датой в один и тот же файл.

base_dir - это целевой каталог, и файлы будут иметь вид & lt; date & gt; .txt . Примечание: существующие файлы не будут перезаписаны, новые строки будут добавлены из-за перенаправления & gt; & gt; & gt; , поэтому лучше убедиться, что целевой каталог не содержит файлов формы & Lt; дата & GT;.

.txt
6
ответ дан 6 August 2018 в 03:58

Я использовал бы {x..y}, возможно, для y, m, d cascading, shema:

  для d в {18..19};  do grep 200901 $ d datadata;  эхо;  сделано 20090118025859 -2.400000 78.100000 1023.200000 0.000000 20090118025900 -2.500000 78.100000 1023.200000 0.000000 20090118025901 -2.400000 78.100000 1023.200000 0.000000 20090119025859 -2.400000 78.100000 1023.200000 0.000000 20090119025900 -2.500000 78.100000 1023.200000 0.000000 20090119025901 -2.400000 78.100000 1023.200000 0.000000  
0
ответ дан 6 August 2018 в 03:58

Возможно, это сработает для вас:

  awk '{d = substr ($ 1, 1, 8);  fn = "data" d ".dat";  напечатать $ 0 & gt; & gt;  fn} 'Огромный файл  
1
ответ дан 6 August 2018 в 03:58

Я использовал бы {x..y}, возможно, для y, m, d cascading, shema:

  для d в {18..19};  do grep 200901 $ d datadata;  эхо;  сделано 20090118025859 -2.400000 78.100000 1023.200000 0.000000 20090118025900 -2.500000 78.100000 1023.200000 0.000000 20090118025901 -2.400000 78.100000 1023.200000 0.000000 20090119025859 -2.400000 78.100000 1023.200000 0.000000 20090119025900 -2.500000 78.100000 1023.200000 0.000000 20090119025901 -2.400000 78.100000 1023.200000 0.000000  
0
ответ дан 7 August 2018 в 21:55

Возможно, это сработает для вас:

  awk '{d = substr ($ 1, 1, 8);  fn = "data" d ".dat";  напечатать $ 0 & gt; & gt;  fn} 'Огромный файл  
1
ответ дан 7 August 2018 в 21:55

Предполагая, что файл отсортирован и даты всегда существуют, это должно работать:

  #! / bin / bash base_dir = '. /' во время чтения строки;  do date = "$ {line: 0: 8}" echo "$ line" & gt; & gt; & gt; & gt;  "$ base_dir $ date.txt" done & lt;  «$ 1»  

[Сохраните его как my_splitter , сделайте его выполнимым, запустив chmod + x my_splitter , затем назовите его как ./ my_splitter input_file ]

Он считывает входной файл по строкам, извлекает дату и использует это, чтобы добавить строки с той же датой в один и тот же файл.

base_dir - это целевой каталог, и файлы будут иметь вид & lt; date & gt; .txt . Примечание: существующие файлы не будут перезаписаны, новые строки будут добавлены из-за перенаправления & gt; & gt; & gt; , поэтому лучше убедиться, что целевой каталог не содержит файлов формы & Lt; дата & GT;.

.txt
6
ответ дан 7 August 2018 в 21:55

Возможно, это сработает для вас:

  awk '{d = substr ($ 1, 1, 8);  fn = "data" d ".dat";  напечатать $ 0 & gt; & gt;  fn} 'Огромный файл  
1
ответ дан 10 August 2018 в 10:10

Предполагая, что файл отсортирован и даты всегда существуют, это должно работать:

  #! / bin / bash base_dir = '. /' во время чтения строки;  do date = "$ {line: 0: 8}" echo "$ line" & gt; & gt; & gt; & gt;  "$ base_dir $ date.txt" done & lt;  «$ 1»  

[Сохраните его как my_splitter , сделайте его выполнимым, запустив chmod + x my_splitter , затем назовите его как ./ my_splitter input_file ]

Он считывает входной файл по строкам, извлекает дату и использует это, чтобы добавить строки с той же датой в один и тот же файл.

base_dir - это целевой каталог, и файлы будут иметь вид & lt; date & gt; .txt . Примечание: существующие файлы не будут перезаписаны, новые строки будут добавлены из-за перенаправления & gt; & gt; & gt; , поэтому лучше убедиться, что целевой каталог не содержит файлов формы & Lt; дата & GT;.

.txt
6
ответ дан 10 August 2018 в 10:10

Я использовал бы {x..y}, возможно, для y, m, d cascading, shema:

  для d в {18..19};  do grep 200901 $ d datadata;  эхо;  сделано 20090118025859 -2.400000 78.100000 1023.200000 0.000000 20090118025900 -2.500000 78.100000 1023.200000 0.000000 20090118025901 -2.400000 78.100000 1023.200000 0.000000 20090119025859 -2.400000 78.100000 1023.200000 0.000000 20090119025900 -2.500000 78.100000 1023.200000 0.000000 20090119025901 -2.400000 78.100000 1023.200000 0.000000  
0
ответ дан 10 August 2018 в 10:10

Возможно, это сработает для вас:

  awk '{d = substr ($ 1, 1, 8);  fn = "data" d ".dat";  напечатать $ 0 & gt; & gt;  fn} 'Огромный файл  
1
ответ дан 13 August 2018 в 16:31

Предполагая, что файл отсортирован и даты всегда существуют, это должно работать:

  #! / bin / bash base_dir = '. /' во время чтения строки;  do date = "$ {line: 0: 8}" echo "$ line" & gt; & gt; & gt; & gt;  "$ base_dir $ date.txt" done & lt;  «$ 1»  

[Сохраните его как my_splitter , сделайте его выполнимым, запустив chmod + x my_splitter , затем назовите его как ./ my_splitter input_file ]

Он считывает входной файл по строкам, извлекает дату и использует это, чтобы добавить строки с той же датой в один и тот же файл.

base_dir - это целевой каталог, и файлы будут иметь вид & lt; date & gt; .txt . Примечание: существующие файлы не будут перезаписаны, новые строки будут добавлены из-за перенаправления & gt; & gt; & gt; , поэтому лучше убедиться, что целевой каталог не содержит файлов формы & Lt; дата & GT;.

.txt
6
ответ дан 13 August 2018 в 16:31
  • 1
    Вместо $ (echo «$ line» | cut -b 1-8) вы можете сделать $ {line: 0: 8} , что короче и эффективнее , [D0] mywiki.wooledge.org/BashSheet#Parameter_Operations – geirha 3 March 2011 в 02:07
  • 2
    @geirha Спасибо, отредактирован. – htorque 3 March 2011 в 02:14

Я использовал бы {x..y}, возможно, для y, m, d cascading, shema:

  для d в {18..19};  do grep 200901 $ d datadata;  эхо;  сделано 20090118025859 -2.400000 78.100000 1023.200000 0.000000 20090118025900 -2.500000 78.100000 1023.200000 0.000000 20090118025901 -2.400000 78.100000 1023.200000 0.000000 20090119025859 -2.400000 78.100000 1023.200000 0.000000 20090119025900 -2.500000 78.100000 1023.200000 0.000000 20090119025901 -2.400000 78.100000 1023.200000 0.000000  
0
ответ дан 13 August 2018 в 16:31

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

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