Поиск дубликатов блоков текста в файле с использованием сценария оболочки

Скажем, у меня есть текстовый файл со следующими строками: –

abcd/efgh/a.jar { abcd/efgh/a.class cdef/ghij/b.class klmn/opqr/c.class } lkmn/opqr/b.zip { abcd/efgh/a.class cdef/ghij/b.class } abcd/efgh/a.jar { cdef/ghij/b.class } 

Теперь abcd / efgh / a.jar в первом случае имеет abcd / efgh / a.class, cdef / ghij / b.class и klmn / opqr / c.class в фигурных скобках. Рассмотрите это как 1 блок текста. Теперь abcd / efgh / a.jar ниже имеет cdef / ghij / b.class в фигурных скобках. Я хочу удалить этот раздел / блок текста. Таким образом, конечный результат должен быть следующим: –

 abcd/efgh/a.jar { abcd/efgh/a.class cdef/ghij/b.class klmn/opqr/c.class } lkmn/opqr/b.zip { abcd/efgh/a.class cdef/ghij/b.class } 

Любая помощь будет высоко оценен 🙂

3 Solutions collect form web for “Поиск дубликатов блоков текста в файле с использованием сценария оболочки”

использование

 for i in `awk '/}/ {if (NR!=1) print "";next} \ {printf "%s ",$0,"}"}END{print ""}' yt.txt \ |awk '{print $1}'|sort|uniq \ `; \ do \ awk '/}/ {if (NR!=1) print "";next} \ {printf "%s ",$0,"}"}END{printf ""} \ ' yt.txt \ |grep "$i"|sed 's/ /\n/g'|grep -v "$i"|sort|uniq \ |awk -v var="$i" ' NR==1 {printf var} {print $0} END {print "}"}' \ ;done \ 

Та же команда в 1 строке ниже (для цели копирования)

 for i in `awk '/}/ {if (NR!=1) print "";next} {printf "%s ",$0,"}"}END{print ""}' yt.txt|awk '{print $1}'|sort|uniq` ; do awk '/}/ {if (NR!=1) print "";next} {printf "%s ",$0,"}"}END{printf ""}' yt.txt|grep "$i"|sed 's/ /\n/g'|grep -v "$i"|sort|uniq|awk -v var="$i" ' NR==1 {printf var} {print $0} END {print "}"}' ;done 

Объяснение:

Часть будет возвращать вам уникальный заголовок блока ( abcd/efgh/a.jar , lkmn/opqr/b.zip ) и передать его для блокировки. Часть do сначала grep все строки для каждого заголовка, в том числе дубликаты. Затем он исключает заголовок и объединяет все остальные строки под этим заголовком, а затем добавляет заголовок в первую строку. И hardcode } в конце.

пример

 bash-4.2$ cat yt.txt abcd/efgh/a.jar { abcd/efgh/a.class cdef/ghij/b.class klmn/opqr/c.class } lkmn/opqr/b.zip { abcd/efgh/a.class cdef/ghij/b.class } abcd/efgh/a.jar { cdef/ghij/b.class d.class } bash-4.2$ for i in `awk '/}/ {if (NR!=1) print "";next} {printf "%s ",$0,"}"} \ > END{print ""}' yt.txt |awk '{print $1}'|sort|uniq` \ > ; do awk '/}/ {if (NR!=1) print "";next} {printf "%s ",$0,"}"}END{printf ""}' yt.txt \ > |grep "$i"|sed 's/ /\n/g'|grep -v "$i"|sort|uniq \ > |awk -v var="$i" ' NR==1 {printf var} {print $0} END {print "}"}'\ > ;done abcd/efgh/a.jar { abcd/efgh/a.class cdef/ghij/b.class d.class klmn/opqr/c.class } lkmn/opqr/b.zip { abcd/efgh/a.class cdef/ghij/b.class } 

После того, как я увидел решение, использующее цикл for с awk и sort и uniq и grep и sed я попробовал решение с одним инструментом вместо шести:

 sed ':a N;$!ba y/\n_/_\n/;s/^/_/ :b s/\(_[^_]*_{\)\([^}]*\)\(_[^_}]*\)\(_[^}]*\)\(_}.*\)\1\([^}]*\)\3_/\1\2\3\4\5\1\6_/;tb :c s/\(_[^_]*_{\)\([^}]*\)_}\(.*\)\1\([^}]*\)_}/\1\2\4_}\3/;tc s/^_// y/\n_/_\n/' yourfile 

делает работу, но я должен признать, что регулярные выражения легче писать, чем читать … (-;

 perl -alF'/\n[}{]\n/' -0777ne ' for ( 0 .. $#F/2 ) { my $i = 2*$_; my($k,$v) = @F[$i,$i+1]; if ( exists $h{$k} ) { $h{$k} .= join $\, grep { ! exists $seen{$k,$_} } split $\, $v; } else { push @k, $k; $seen{$k,$_}++ for split $\, $h{$k} = $v; } } print "$_\n{\n$h{$_}\n}" for @k; ' yourfile 

Результаты

 abcd/efgh/a.jar { abcd/efgh/a.class cdef/ghij/b.class klmn/opqr/c.class } lkmn/opqr/b.zip { abcd/efgh/a.class cdef/ghij/b.class } 

За работой

Входной файл разрывается, а затем разбивается на поля на основе разделителя полей, указанного параметром -F . Мы получим четное число элементов в массиве @F . Четные числа затем входят в качестве ключей хеша %h то время как их корреспондент. значения захватываются из следующего нечетного значения.

Хеш %h заполняется разбиением нечетных номеров на разделителе записей ($ \ = \ n). В то же время мы @k ключ в массив @k чтобы мы могли извлекать хэш-элементы, чтобы они встречались.

Все это время используются только те нечетные элементы, которые еще не видели.

  • Заменить второе и последнее вхождение строки в каждой строке
  • Добавить круглые скобки вокруг чисел
  • AIX - нужно добавить строки после идентификации шаблона в файле с помощью Non-GNU - Sed
  • Команда для хранения строк с определенной длиной в файле
  • Есть ли заклинание командной строки для удаления столбца в CSV-файле?
  • Выбирать и удалять строки, соответствующие шаблону из файла
  • Диагональный вывод файла
  • Выбор строки из шаблона, замена новой строки и увеличение количества для каждого изменения
  • получить столбец из файла на основе другого столбца
  • Как я могу удалить все символы, попадающие под / * ... * / includes / * & * /?
  • Добавить ;; вверху и внизу каждого файла в списке
  • Linux и Unix - лучшая ОС в мире.