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

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

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 чтобы мы могли извлекать хэш-элементы, чтобы они встречались.

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

  • файл формата для удаления "символов
  • Выведите отрицательные значения, независимо от оригинала, на выбранных линиях
  • Использовать вывод cat или grep как вход в sed
  • Изменить Прямые цитаты на смарт-цитаты, не жертвуя переносом слов
  • объединить два текстовых файла с добавлением разделителя между ними?
  • Как переформатировать строку времени в нескольких файлах?
  • Сохраняйте символы до и после определенного символа
  • Как настроить числовые поля в текстовом файле
  • Печать всех строк между найденным шаблоном текстового файла в другой файл
  • Как проверить, имеет ли файл разделитель табуляции и имеет 8 столбцов?
  • транспонировать наборы из трех строк в столбцы
  • Interesting Posts

    Поиск нескольких вхождений определенного символа в tcsh

    Улучшить рендеринг шрифтов в Fedora

    создать прослушивающий порт на IPV6 БЕЗ netcat

    Как использовать беспроводную сеть в Virtualbox?

    CentOS7: удалить nvidia-x11-drv-340xx хочет удалить весь xorg

    Использование tar в файле с символом @ (при символе)

    Как создать пакет Archlinux с нуля

    Временное рассмотрение всех файлов повестки дня

    где находится файл журнала Gnome 3?

    Сегмент отображения памяти и куча растут, пока они не встретятся друг с другом?

    Bash: разрешить круглые скобки в аргументах команды (т.е. предотвратить «неожиданный токен» (‘”)

    Нужно ли увеличить размер исходного раздела, если я просто восстанавливаю содержимое (с помощью dd)?

    Почему моя панель инструментов Emacs отличается от ssh w / X forwarding на Cygwin vs CentOS?

    Почему установка переменной перед командой legal в bash?

    Как установить верхний предел для значения PCM при изменении громкости с помощью pulseaudio?

    Linux и Unix - лучшая ОС в мире.