Разделение одного большого файла на несколько, если текст в столбце не совпадает с текстом в предыдущем - PullRequest
0 голосов
/ 30 мая 2018

Я некоторое время искал и не мог найти ответ на это.У меня есть стандартный файл TSV в следующем формате:

1    100    101    350    A
1    101    102    300    A
1    102    103    180    A
1    800    801    60     B
1    801    802    70     B
1    802    803    82     B
1    975    976    105    C
1    976    977    108    C

и т. Д.Это продолжается для нескольких миллионов строк, и в столбце 5 есть 1000 различных регионов (A, B, C).Все регионы имеют разные размеры с точки зрения количества линий.Я хотел бы перебрать файл и разделить каждый регион на отдельный файл.

FileA.txt

1    100    101    350    A
1    101    102    300    A
1    102    103    180    A

FileB.txt

1    800    801    60     B
1    801    802    70     B
1    802    803    82     B

FileC.txt

1    975    976    105    C
1    976    977    108    C

Ответы [ 4 ]

0 голосов
/ 30 мая 2018

С awk

awk '{out = "File" $NF ".txt"; print >> out; close(out)}' file

Более эффективно, не закрывая файл назначения после каждой строки:

awk '
    $NF != dest {if (out) close(out); dest = $NF; out = "File" dest ".txt"} 
    {print >> out}
' file
0 голосов
/ 30 мая 2018

Итак, используя grep, что-то вроде:

for L in `grep -oE '[A-Z]+$'|uniq|sort|uniq`
do
grep -E ${L}'$' > file.${L}.txt
done 

Фраза grep -oE '[A-Z]+$'|uniq|sort|uniq должна найти все уникальные ключи, которые вы затем используете для повторного анализа файла несколько раз.Последовательность uniq | sort | uniq предназначена для уменьшения входных данных для сортировки.

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

0 голосов
/ 30 мая 2018

Таким образом, поэтапный подход с использованием однопроходного сценария с низким объемом памяти:

while IFS=" " read -r value1 value2 value3 value4 value5 remainder
do
  echo $value1 $value2 $value3 $value4 $value5 $remainder >> output.${value5}.txt
done < "input.txt"

Конечно, вы должны убедиться, что нет уже существующих выходных файлов, но это может быть достигнуто числомспособов эффективно.

0 голосов
/ 30 мая 2018

Вот небольшое решение в Python, использующее groupby и str.rpartition:

from itertools import groupby

with open("in_file.txt") as f_in:
for name,lines in groupby(f_in.readlines(),key=lambda x:x.rpartition(" ")[2].strip()):
        with open(f"out_{name}.txt","w") as f_out:
            f_out.writelines(lines)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...