Как разбить текстовые файлы по количеству строк, что соответствует другому набору файлов?

Разрезать файл на несколько файлов по номерам в списке:

$ wc -l all.txt
    8500   all.txt

$ wc -l STS.*.txt  
   2000 STS.input.answers-forums.txt
   1500 STS.input.answers-students.txt
   2000 STS.input.belief.txt
   1500 STS.input.headlines.txt
   1500 STS.input.images.txt

Как мне разделить мой all.txt в № из линий STS.*.txtа затем сохранить их в соответствующиеSTS.output.*.txt?

Я делал это вручную как так:

$ sed '1,2000!d' all.txt > STS.output.answers-forums.txt
$ sed '2001,3500!d' all.txt > STS.output.answers-students.txt
$ sed '3501,5500!d' all.txt > STS.output.belief.txt
$ sed '5501,7000!d' all.txt > STS.output.headlines.txt
$ sed '7001,8500!d' all.txt > STS.output.images.txt

all.txt вход будет выглядеть примерно так:

$ head all.txt
2.3059
2.2371
2.1277
2.1261
2.0576
2.0141
2.0206
2.0397
1.9467
1.8518

Или иногда all.txt выглядит так:

$ head all.txt
2.3059  92.123
2.2371  1.123
2.1277  0.12452
2.1261123   213
2.0576  100
2.0141  0
2.02062 1
2.03972 34.123
1.9467  9.23
1.8518  9123.1

Что касается STS.*. Txt, то это просто строки текста, например:

$ head STS.output.answers-forums.txt
The problem likely will mean corrective changes before the shuttle fleet starts flying again.   He said the problem needs to be corrected before the space shuttle fleet is cleared to fly again.
The technology-laced Nasdaq Composite Index .IXIC inched down 1 point, or 0.11 percent, to 1,650.   The broad Standard & Poor's 500 Index .SPX inched up 3 points, or 0.32 percent, to 970.
"It's a huge black eye," said publisher Arthur Ochs Sulzberger Jr., whose family has controlled the paper since 1896.   "It's a huge black eye," Arthur Sulzberger, the newspaper's publisher, said of the scandal.

2 ответа

Решение

Хотелось бы, чтобы вы опубликовали пример входных данных для разбиения входного файла, скажем, 10 строк на выходные файлы, скажем, 2, 3 и 5 строк вместо 8500 строк на...., поскольку это дало бы нам возможность что-то проверить решение против. Ну что ж, это может сработать, но, конечно, не проверено:

awk '
ARGIND < (ARGC-1) { outfile[NR] = gensub(/input/,"output","",FILENAME); next }
{ print > outfile[FNR] }
' STS.input.* all.txt

Выше использовались GNU awk для ARGIND и gensub().

Он просто создает массив, который сопоставляет каждый номер строки во всех "входных" файлах с именем "выходного" файла, в который должен быть записан тот же номер строки "all.txt".

Каждый раз, когда вы пишете цикл в оболочке только для манипулирования текстом, у вас неправильный подход. Ребята, которые создали shell, также создали awk для shell, чтобы вызывать для манипулирования текстом, так что просто сделайте это.

Я бы предложил написать цикл:

for file in answers-forums answers-students belief headlines images; do
    lines=$(wc -l < "STS.input.$file.txt")
    sed "$(( total + 1 )),$(( total + lines ))!d" all.txt > "STS.output.$file.txt"
    (( total += lines ))
done

total отслеживает, сколько строк было прочитано до сих пор. Команда sed извлекает строки из total + 1 в total + lines, записав их в соответствующий выходной файл.

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