2017-02-17 1 views
2

Я хочу разбить текстовый файл, подобный тому, который был вставлен ниже (извините за длину), на каждое n вхождение «>». Например, каждое второе появление «>», но мне нужно иметь возможность изменить это число.Awk: Разделение файла на n-ом вхождении разделителя, неправильный первый файл с разделом

test_split.txt:

>eeefkdfn 
a 
a 
a 
>c 4ufjdhf 
b 
b 
b 
b 
> 
c 
c 
> c 
d 
d 
d 
d 
d 
>3 
>cr 
>c3 
e 
e 
e 
e 
e 
> 5 
f 
f 
f 
f 
>cr 
g 
g 
g 
g 
> cr dkjfddf 
h 
h 
h 
h 

Так что я хочу, чтобы выходные файлы этого они (только показывая первые два):

file_1.txt:

>eeefkdfn 
a 
a 
a 
>c 4ufjdhf 
b 
b 
b 
b 

file_2.txt :

> 
c 
c 
> c 
d 
d 
d 
d 
d 

и т.д.

Вопрос:

Я пытался достичь этого результата с помощью этой команды AWK:

awk '/^>/ {n++} { file = sprintf("file_%s.txt", int(n/2)); print >> file; }' < test_split.txt 

И вместо желаемого результата, я получаю правильный выходные файлы (Split),

кошка test_0.txt

>eeefkdfn 
a 
a 
a 
: для первого, который содержит только один вхождение «>» (вместо двух), как это, за исключением

кошка test_1.txt

>chr1 4ufjdhf 
b 
b 
b 
b 
> 
c 
c 

Любая идея, почему это? Спасибо!

+1

Немного сложно понять, чего вы пытаетесь достичь и какова ваша проблема. Могу ли я предложить вам любезно перефразировать ваш вопрос с небольшой консолидацией и четко выделить «Проблемную часть» и «Вопрос-часть», что облегчит нам понимание и поможет вам с этим вопросом. Благодарю. – User9102d82

+0

Отредактировано мое сообщение немного, я надеюсь, что это яснее! Если не сообщите мне, что не хватает – arielle

+0

Поменяйте порядок ваших приращений и разделов печати. Вы увеличиваете до первого раздела. – stark

ответ

2

Это кажется более простым:

awk 'BEGIN{i=1}/^>/{cont++}cont==3{i++;cont=1}{print > "file_"i".txt"} file 

Воля дает ожидаемый результат:

$ cat file_1.txt 
>eeefkdfn 
a 
a 
a 
>c 4ufjdhf 
b 
b 
b 
b 

$ cat file_2.txt 
> 
c 
c 
> c 
d 
d 
d 
d 
d 

Пояснение

BEGIN{i=1}: Файл инициализации счетчика.

/^>/{cont++}: Для подсчета каждых > найдено.

cont==3{i++;cont=1}: Чтобы увеличить счетчик файлов и инициализировать cont var каждый третий вид символа >, который снова становится первым.

{print > "file_"i".txt"}: Направьте вывод на ожидаемый файл.

+0

Когда вход большой, он оставит много незакрытых ручек файлов. – anubhava

+0

@anubhava Что вы подразумеваете под открытыми файловыми дескрипторами (пытались найти его, но не нашли много) – arielle

+0

(Я все еще новичок), можете ли вы объяснить часть == 3 {i ++; cont = 1}, пожалуйста? Почему == 3? Благодаря! – arielle

1

Вы можете использовать эту AWK для динамического контроля над номером n, где файл будет разделен на nth появлении > в исходных данных:

awk -v n=2 'function ofile() { 
    if (op) 
     close(op) 
    op = sprintf("file_%d.txt", ++p) 
} 
BEGIN { 
    ofile() 
} 
/>/ { 
    ++i 
} 
i > n { 
    i=1 
    ofile() 
} 
{ 
    print $0 > op 
} 
END { 
    close(op) 
}' file 

Вот один вкладыш в случае, если вы хотите скопировать/вставить:

awk -v n=2 'function ofile() {if (op) close(op); op = sprintf("file_%d.txt", ++p)} BEGIN{ofile()} />/{++i} i>n{i=1; ofile()} { print $0 > op }' file 
+1

Он хорошо работает, спасибо! Если бы я мог поставить два ответа, я бы выбрал это тоже – arielle

Смежные вопросы