Как разбить текстовые файлы по количеству строк, что соответствует другому набору файлов?
Разрезать файл на несколько файлов по номерам в списке:
$ 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
, записав их в соответствующий выходной файл.