фильтрация данных на основе разделителя в оболочке

фильтрация данных на основе разделителя в оболочке

У меня есть файл с данными следующего содержания:

"google1|yoo|dummy|yes|wow|/" + VARIABLE + "/"
"google2|hub|lab|dummy|yes|/" + VARIABLE + "/"
"google3|short|lab|yoo|/" + VARIABLE + "/"
"google4|hello|good-guy|bad-girl|lol|dummy|/" + VARIABLE + "/"
"google5|good-guy|a4-123|yoo|/" + VARIABLE + "/"
"google6|bad-girl|b4-124|hub|/" + VARIABLE + "/"

Теперь я хочу получить список строк между разделителем «|» (вертикальная черта).

Вывод должен быть таким

yoo
dummy
yes
wow
hub
hello
good-guy
bad-girl
a4-123
b4-124
dummy
lol
short
lab

В принципе, я хочу иметь уникальные значения из списка строк после фильтра-разделителя. Я пробовал использовать awk как

awk -F"|" '{gsub(/\).*/,"",$2);print $2}' file

Но я получаю неверные данные.

решение1

Если у вас есть grepопция pcre:

$ grep -oP '\|\K[^|]+(?=\|)' ip.txt | sort -u
a4-123
b4-124
bad-girl
dummy
good-guy
hello
hub
lab
lol
short
wow
yes
yoo
  • -oраспечатать только соответствующий шаблон
  • -Pиспользовать pcre регулярное выражение
  • \|\Kположительный просмотр назад, чтобы увидеть, |есть ли что-то перед нашей строкой, которую нужно извлечь
    • аналогично, (?=\|)положительный просмотр вперед, чтобы увидеть, есть ли |после нашей строки, которая должна быть извлечена
  • [^|]+строка, которую необходимо извлечь - просто отмените |и получите один или несколько таких символов
  • sort -uчтобы получить уникальную ценность

Если вы хотите сохранить порядок, в котором находятся эти строки:

$ grep -oP '\|\K[^|]+(?=\|)' ip.txt | awk '!seen[$0]++'
yoo
dummy
yes
wow
hub
lab
short
hello
good-guy
bad-girl
lol
a4-123
b4-124

решение2

Если вас не волнует порядок, вы можете использовать хеш Perl для обеспечения уникальности, например:

$ perl -lne '$h{$_}++ for /(?<=\|).*?(?=\|)/g; END{print for keys %h}' file
short
b4-124
lol
yes
bad-girl
lab
yoo
good-guy
hub
dummy
hello
a4-123
wow

Видетьсоздание хеша с совпадениями регулярных выражений в Perl

решение3

а как насчет следующего?

cut file -d'|' -f2,3,4 | tr '|' '\n'

Приведенная выше команда выведет фиксированное количество столбцов (3). Если вы хотите вывести переменное количество столбцов, до первого появления /, вы можете использовать что-то вроде:

cut -d'/' -f1 file | cut  -d'|' -f2- | tr '|' '\n'

решение4

Ваш вывод имеет "фиктивный" повтор. Это то, что я получаю с помощью скрипта ниже --

   awk -f f1.awk /tmp/f1
    short
    hub
    wow
    hello
    a4-123
    b4-124
    yes
    yoo
    lol
    bad-girl
    good-guy
    lab
    dummy

    cat f1.awk 
    {
      n=split($1,a,"|")

      for(i=2; i<n; i++) {
        arr[a[i]] = a[i] 
      } 
    }   
    END{
      for (var in arr) 
        print(var)  
    }

Связанный контент