
У меня есть большой файл длиной в пару сотен строк. Этот файл разделен на множество частей по определенному идентификатору, скажем, «ABC». Эта строка «ABC» встречается 6 раз, поэтому мне нужно 6 выходных файлов. Я знаком с split и awk, но не могу создать командную строку, которая будет делать то, что я описал, есть идеи?
Вот пример
ABC
line 1
line 2
line 3
ABC
line 1
line 2
ABC
line1
Мне нужны три файла, где ABC — первая строка в новом файле, и она заканчивается до того, как встретится следующая ABC.
решение1
С использованиемcsplit
csplit -z somefile /ABC/ '{*}'
Выходные файлы будут иметь вид xx00
, xx01
, ... по умолчанию, но при желании вы можете изменить формат и нумерацию — см.man csplit
решение2
NEEDLE=ABC
HAYSTACK=/path/to/bigfile
csplit -f splitfile_ $HAYSTACK /$NEEDLE/ "{$(($(grep -c -- $NEEDLE $HAYSTACK)-1))}"
for file in splitfile_*; do
sed --in-place "s/$NEEDLE//" $file
done
Вышеуказанное разделит файл, как запрошено, независимо от того, сколько экземпляров линии маркера у вас есть, а затем удалит маркер из результирующих файлов. Выходные файлы будут называться, например splitfile_00
, splitfile_01
, и так далее.
Разберем этот фрагмент в конце вызова csplit
: "{$(($(grep -c $NEEDLE HAYSTACK)-1))}"
Мы используем подоболочку, grep
чтобы получить количество экземпляров вашего маркера в файле, и вычитаем единицу — это csplit
точно сообщает, сколько разделений он собирается сделать.
Обратите внимание, что, как написано выше, все может пойти не так, если ваш маркер появится в данных.