Получение по запросу конкретного блока от текстового файла

Я пытаюсь вытащить блок данных из огромного текстового файла, который содержит 1 193 373 557 строк.

Я исключаю первые 25 строк и последние 4 строки, и более сложное задание - то, что остающийся блок содержит данные, которые сделаны из 2 заголовков; я хочу разделить эти данные на основе заголовка файла.

Пример: test.txt (этот файл содержит данные header1 и header2),

header1
------
----
----
----
header2
-----
----
----
---

Требуемый вывод:

  • header1.txt: в этом файле все строки должны быть там, пока header2 не запускается
  • header2.txt: все строки после header1 должны распечатать
-1
задан 15 January 2016 в 12:04

2 ответа

Использование AWK:

awk -v nlines=$(wc -l test.txt | cut -d ' ' -f 1) '$0=="Reading input from PoolA_Rnase", $0=="Reading input from PoolB_Rnase" {if($0 != "Reading input from PoolB_Rnase") {print >"header1.txt"}} $0=="Reading input from PoolB_Rnase", NR==nlines-4 {print >"header2.txt"}' test.txt

Сценарий AWK расширен и прокомментирован:

  • nlines содержит количество строк в файле, вычисленном через $(wc -l test.txt | cut -d ' ' -f 1).
$0=="Reading input from PoolA_Rnase", $0=="Reading input from PoolB_Rnase" { # if the current record is between a record matching "Reading input from PoolA_Rnase" and a record matching "Reading input from PoolB_Rnase" inclusive
    if($0 != "Reading input from PoolB_Rnase") { # if the current record doesn't match "Reading input from PoolB_Rnase"
        print >"header1.txt" # prints the record to header1.txt
    }
}
$0=="Reading input from PoolB_Rnase", NR==nlines-4 { # if the current record is between a record matching "Reading input from PoolB_Rnase" and the record number `nlines-4` inclusive
    print >"header2.txt" # prints the record to header2.txt
}
% cat test.txt
line 1
line 2
line 3
line 4
line 5
line 6
line 7
line 8
line 9
line 10
line 11
line 12
line 13
line 14
line 15
line 16
line 17
line 18
line 19
line 20
line 21
line 22
line 23
line 24
line 25
Reading input from PoolA_Rnase
foo
foo
foo
Reading input from PoolB_Rnase
bar
bar
bar
line 1
line 2
line 3
line 4
% awk -v nlines=$(wc -l test.txt | cut -d ' ' -f 1) '$0=="Reading input from PoolA_Rnase", $0=="Reading input from PoolB_Rnase" {if($0 != "Reading input from PoolB_Rnase") {print >"header1.txt"}} $0=="Reading input from PoolB_Rnase", NR==nlines-4 {print >"header2.txt"}' test.txt
% cat header1.txt 
Reading input from PoolA_Rnase
foo
foo
foo
% cat header2.txt 
Reading input from PoolB_Rnase
bar
bar
bar
0
ответ дан 29 September 2019 в 14:10

Для header1.txt:

sed -n '/^header1$/,/^header2$/{/^header2$/d;p}' file >header1.txt
  • /pattern1/,/pattern2/ этот синтаксис sed соответствия все между (и включая) pattern1 и pattern2.
  • /^header2$/d это удалит header2 строку, потому что это не нужно.
  • p остальные будут распечатаны.

Для header2.txt:

sed -n '/^header2$/,$p' file >header2.txt
  • Подобный первой команде, это соответствует от header2 к последней строке $.
1
ответ дан 29 September 2019 в 14:10

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

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