У меня есть текстовый файл, entry.txt
который содержит следующее:
[ entry1 ]
1239 1240 1242 1391 1392 1394 1486 1487 1489 1600
1601 1603 1657 1658 1660 2075 2076 2078 2322 2323
2325 2740 2741 2743 3082 3083 3085 3291 3292 3294
3481 3482 3484 3633 3634 3636 3690 3691 3693 3766
3767 3769 4526 4527 4529 4583 4584 4586 4773 4774
4776 5153 5154 5156 5628 5629 5631
[ entry2 ]
1239 1240 1242 1391 1392 1394 1486 1487 1489 1600
1601 1603 1657 1658 1660 2075 2076 2078 2322 2323
2325 2740 2741 2743 3082 3083 3085 3291 3292 3294
3481 3482 3484 3690 3691 3693 3766 3767 3769 4526
4527 4529 4583 4584 4586 4773 4774 4776 5153 5154
5156 5628 5629 5631
[ entry3 ]
1239 1240 1242 1391 1392 1394 1486 1487 1489 1600
1601 1603 1657 1658 1660 2075 2076 2078 2322 2323
2325 2740 2741 2743 3082 3083 3085 3291 3292 3294
3481 3482 3484 3690 3691 3693 3766 3767 3769 4241
4242 4244 4526 4527 4529 4583 4584 4586 4773 4774
4776 5153 5154 5156 5495 5496 5498 5628 5629 5631
Я хотел бы разделить его на три текстовых файлов: entry1.txt
, entry2.txt
, entry3.txt
. Их содержание заключается в следующем.
entry1.txt :
[ entry1 ]
1239 1240 1242 1391 1392 1394 1486 1487 1489 1600
1601 1603 1657 1658 1660 2075 2076 2078 2322 2323
2325 2740 2741 2743 3082 3083 3085 3291 3292 3294
3481 3482 3484 3633 3634 3636 3690 3691 3693 3766
3767 3769 4526 4527 4529 4583 4584 4586 4773 4774
4776 5153 5154 5156 5628 5629 5631
entry2.txt :
[ entry2 ]
1239 1240 1242 1391 1392 1394 1486 1487 1489 1600
1601 1603 1657 1658 1660 2075 2076 2078 2322 2323
2325 2740 2741 2743 3082 3083 3085 3291 3292 3294
3481 3482 3484 3690 3691 3693 3766 3767 3769 4526
4527 4529 4583 4584 4586 4773 4774 4776 5153 5154
5156 5628 5629 5631
entry3.txt :
[ entry3 ]
1239 1240 1242 1391 1392 1394 1486 1487 1489 1600
1601 1603 1657 1658 1660 2075 2076 2078 2322 2323
2325 2740 2741 2743 3082 3083 3085 3291 3292 3294
3481 3482 3484 3690 3691 3693 3766 3767 3769 4241
4242 4244 4526 4527 4529 4583 4584 4586 4773 4774
4776 5153 5154 5156 5495 5496 5498 5628 5629 5631
Другими словами, [
символ указывает, что новый файл должен начинаться. Записи ( [ entry*]
где *
целое число) всегда в числовом порядке и являются последовательными целыми числами, начиная с 1 до N (в моем реальном входном файле N = 200001).
Есть ли способ, которым я могу выполнить автоматическое разбиение текстового файла в Bash? Мой фактический вклад entry.txt
фактически содержит 200 001 записей.
источник
match
входить:/^\[/ { name=$2 }
должно быть достаточно.[ blahblah blah blah ]
в своем ответе.FS
, кто , например, с-F '\\[ | \\]'
.#S x
, где х - 1, 2 или 3-значное число. Достаточно просто сохранить их в x.dat. Я попробовал:gawk '/^#S/{match($0, / [0-9]* /, k)} {print >k[1]".dat" }' myFile.txt
и некоторые варианты этого.gawk '/^#S/{match($0, /^#S (\s+?)([0-9]+)(\s+?)/, k)} {print >k[2]".txt" }' test.txt
. Не2
очень хорошо понимаю номер массива .С помощью csplit из GNU coreutils (не встроенный Linux, Cygwin):
Вы получите дополнительный пустой файл
entry0.txt
(содержащий часть перед первым заголовком).Стандартному csplit не хватает
{*}
неопределенного повторителя и-b
возможности указать формат суффикса, поэтому в других системах вам придется сначала подсчитать количество разделов и переименовать выходные файлы.источник
В Perl это можно сделать гораздо проще:
источник
Вот короткая awk с одним вкладышем:
Как это работает?
/^\[/
сопоставляет строки, начинающиеся с левой квадратной скобки, и{ofn=$2 ".txt"}
устанавливает переменную для второго слова с пробелами в качестве имени нашего выходного файла. Потом,ofn
условие, которое оценивается как true, если переменная установлена (таким образом, строки перед вашим первым заголовком игнорируются){print > ofn}
перенаправляет текущую строку в указанный файл.Обратите внимание, что все пробелы в этом скрипте awk могут быть удалены, если компактность делает вас счастливыми.
Также обратите внимание, что приведенному выше сценарию действительно нужны заголовки разделов, чтобы они были внутри, а не внутри них. Если вы хотите иметь возможность обрабатывать заголовки разделов вроде
[foo]
и[ this that ]
, вам понадобится немного больше кода:Это использует
sub()
функцию awk, чтобы убрать начальные и конечные квадратные скобки плюс пробел. Обратите внимание, что при стандартном поведении awk пробелы (разделитель полей) объединяются в один пробел (т.е.[ this that ]
сохраняются в"this that.txt"
). Если важно сохранить оригинальные пробелы в выходных именах файлов, вы можете поэкспериментировать, установив FS.источник
Это можно сделать из командной строки в Python как:
источник
Это довольно грубый, но легко понятный способ сделать это: используйте,
grep -l '[ entry ]' FILENAME
чтобы разделить номера строк в [entry]. Используйте комбинацию с головы и хвоста, чтобы получить правильные фигуры.Как я сказал; это не красиво, но легко понять.
источник
Как насчет использования awk
[
в качестве разделителя записей и пробела в качестве разделителя полей. Это дает нам легко данные, которые будут помещены в файл,$0
где он должен вернуть удаленное[
ведение и имя файла как$1
. Затем нам нужно обработать только особый случай 1-й записи, который пуст. Это дает нам:источник
Ответ Тердона работает для меня, но мне нужно было использовать gawk, а не awk. В руководстве gawk (поиск по запросу «match (») »объясняется, что аргумент массива в match () является расширением gawk. Возможно, это зависит от вашей установки Linux и ваших версий awk / nawk / gawk, но на моей машине с Ubuntu только gawk запускал отличную версию Terdon. ответ:
источник
Вот решение Perl. Этот скрипт обнаруживает
[ entryN ]
строки и соответственно изменяет выходной файл, но не проверяет, не анализирует и не обрабатывает данные в каждом разделе, он просто печатает входную строку в выходной файл.источник
Привет, я написал этот простой скрипт, используя Ruby, чтобы решить вашу проблему
Вы можете использовать это так:
Я проверил это, и он отлично работает ..
источник
Я предпочитаю
csplit
вариант, но в качестве альтернативы вот решение GNU awk:parse.awk
Запустите это так:
источник
RT
переменная, кажется, специфична для gawk. Это решение не работает для меня, используя awk FreeBSD.