Найти отдельные элементы после вложенного разбиения в Unix - PullRequest
0 голосов
/ 09 июля 2020

У меня есть строка, содержащая несколько значений, разделенных пробелом. Теперь каждое отдельное значение имеет символы, разделенные другим разделителем '-'.

Я ищу хорошее решение с использованием сценария оболочки для поиска уникальных строк в первом поле значений

Чтобы уточнить, мои строка имеет следующий формат

abc-def-ghi 123-456-789 abc-xyp-lmn 789-abc-def

Теперь я хочу найти уникальную строку в первом поле каждой отдельной строки. Итак, в этом массиве «ab c», «123» и «789».

Ответы [ 5 ]

2 голосов
/ 09 июля 2020

Если вас не волнует порядок, это сработает:

echo abc-def-ghi 123-456-789 abc-xyp-lmn 789-abc-def | sed --expression='s/\ /\n/g' | cut -d'-' -f1 | sort | uniq

И если вы хотите получить только количество, добавьте w c -l в конец этого

echo abc-def-ghi 123-456-789 abc-xyp-lmn 789-abc-def | sed --expression='s/\ /\n/g' | cut -d'-' -f1 | sort | uniq | wc -l
1 голос
/ 09 июля 2020

Другой подход, использующий только bash.

#!/usr/bin/env bash

## If the string is not in an array format, use the code below.
##: string='abc-def-ghi 123-456-789 abc-xyp-lmn 789-abc-def'
##: string=${string// / $'\n'}
##: mapfile -t array <<< "$string"

array=(abc-def-ghi 123-456-789 abc-xyp-lmn 789-abc-def)

declare -A uniq

for i in  "${array[@]%%-*}"; do
  ((uniq["$i"]++))
done

printf '%s\n' "${!uniq[@]}"
1 голос
/ 09 июля 2020

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

perl -lnE '
    my %seen; $, = "\n";
    say grep { !$seen{$_}++ } map { (split /-/)[0] } split / /
' file

Вы можете заменить file на здесь-строку :

<<< 'abc-def-ghi 123-456-789 abc-xyp-lmn 789-abc-def'

Вывод

abc
123
789
1 голос
/ 09 июля 2020

Давайте сделаем это коротко:

tr ' ' $'\n' < file | awk -F- '{a[$1]++}END{for (i in a) {print i}}'

Загрузка массива по запросу:

arr=( $(tr ' ' $'\n' < file | awk -F- '{a[$1]++}END{for (i in a) {print i}}') )
printf '%s\n' "${arr[@]}"

abc
123
789
1 голос
/ 09 июля 2020

Использование perl и предположение, что строка находится в переменной bash:

perl -lane 'my %words; $words{(split(/-/, $_))[0]} = 1 for @F; print scalar(keys %words)' <<<"$thevariable"

Если вам нужны уникальные значения, а не их общее количество, print join(" ", keys %words)

...