как с помощью sed,awk,grep вывести уникальные строки с не повторяющимся символами

Рейтинг: 0Ответов: 2Опубликовано: 02.03.2023

Например 123z456z9r89 не правильная строка (в строке пристуствуют одинаковые символы) 123g456z9r8e правильная строка

sed 's/(.)\1/\1/g' выводит только через символ. 1212121

Ответы

▲ 1

один из вариантов:

awk '{cmd="printf "$0" |grep -o . |sort -u |tr -d \"\n\" |wc -m"; cmd |getline z;close(cmd);if(length($0) == z)print}'

где для каждой строки сравнивается длина оригинальной строки с длиной этой же строки но посимвольно-уникально отсортированной, и если длины равны то выводится оригинальная строка.

пример:

$ echo -en "123z456z9r89\n123g456z9r8e\nмама\nмария" |awk '{cmd="printf "$0" |grep -o . |sort -u |tr -d \"\n\" |wc -m"; cmd |getline z;close(cmd);if(length($0) == z)print}'
123g456z9r8e
мария
▲ 0

Скрипт для awk

BEGIN{
    FS="";
}
{
    err=0;
    for(i=1;i<=NF;i++) {
        if(a[$i]++ > 0) {
            err=1;
            break;
        }
    }
    if (!err) { print($0); }
    delete a;
}

FS="" - эта переменная означает, что поля разделены пустыми строками, то есть каждый символ будет отдельным полем

for(i=1;i<=NF;i++) {} цикл по полям, то есть перебирается каждый символ.

if(a[$i]++ > 0) {} в условии стоит постфиксный инкремент, поэтому if сработает, если в массиве a ненулевое значение для символа из $i. Если же такого индекса нет, то a[$i] инициализируется пустым значением, которое потом оператор ++ превратит в 1.

Проверка:

echo -e '1234\nhello\n5432' | awk 'BEGIN{FS="";}{err=0;for(i=1;i<=NF;i++){if(a[$i]++>0){err=1;break;}}if(!err){print($0);}delete a;}'

Печатает 1234 и 5432