2016-11-14 2 views
1

я работаю в Баше и у меня есть большой файл, в котором я хочу, чтобы удалить все строки, которые не соответствуют определенному регулярному выражению, вероятно, используя $ grep -e "<regex>" <file> > output.txtрегулярного выражения появляется символ ровно х раз

То, что я хочу, чтобы сохранить любая линия, которая содержит ровно х раз в указанный символ, например, в двоичной последовательности

0000, 0001, 0010, 0011, 0100, 0101, 0111, 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111

Я хотел бы держать только те, у кого есть 2 , оставив меня с

0011, 0101, 0110, 1001, 1010, 1100

Я бы затем использовать переменную Баш на изменять количество мне нужно (всегда ровно половину длины, работающий со строками одинаковой длины) Я litterally ищет строки, которые наполовину и половина

У меня это прямо сейчас. Он не использует регулярное выражение. Он работает, но очень медленно:

($1 длина каждой строки, $d это просто каталог)

sed -e 's/\(.\)/\1 /g' < $d/input.txt > $d/spaces.txt 
awk '{c=0;for(i=1;i<=NF;++i){c+=$i};print c}' $d/spaces.txt > $d/sums.txt 
grep -n "$(($1/2))" $d/sums.txt | cut -f1 -d: > $d/linenums.txt 
for i in $(cat $d/linenums.txt) 
do 
    sed "${i}q;d" $d/input.txt 
done > $d/valids.txt 

В случае, если интересно, это ставит пробелы между каждой цифрой поворота 1010 в 1 0 1 0, то он добавляет значения вместе, сохраняет результаты в sums.txt, grep для длины/2 и сохраняет только номера строк в linenums.txt, затем читает linenums.txt и выводит соответствующую строку из input.txt в output.txt

Мне нужно что-то более быстрое, цикл for это слишком долгое время

Спасибо за ваше время и за то, что поделились своими знаниями со мной.

+0

Как насчет КИСС? 'grep -E '0011 | 0101 | 0110 | 1001 | 1010 | 1100'' – janos

ответ

2

Вы можете определенно сделать это быстрее.

здесь является grep регулярного выражения примера, чтобы соответствовать любым строкам с точно два вхождением 1:

grep '^\([^1]*1[^1]*\)\{2\}$' input.txt 

вы можете обобщающее это точно соответствовать n вхождениям c:

grep "^\([^$c]*$c[^$c]*\)\{$n\}\$" input.txt 

Вы также упомянули желая соответствовать линиям, которые составляют половину 0 s, половина 1 s. так как вы оговаривал, что все строки имеют одинаковую длину, можно рассматривать только первую строку, и использовать awk (или wc), чтобы получить длину строки и выбрать n:

n=`head -n1 input.txt | awk '{printf "%d\n",length($0)/2}'` 
c=1 
grep "^\([^$c]*$c[^$c]*\)\{$n\}\$" input.txt 
+1

ОК, большое спасибо, он работает, и он работает намного быстрее, чем мой.Работа с небольшими образцовыми файлами заставила меня подумать, что это сработало хорошо, но при работе с записями 65536 (2^16) это показало, насколько медленным было то, что я решил первую часть самостоятельно, но на этот раз я подумал некоторое время! – JFs743

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