To nie dostać rzeczy w oryginalnej kolejności, ale to awk jedno-liner wydaje się działać:
awk '{for(i=1;i<=length($0);i++){a[substr($0,i,1)]=1} for(i in a){printf("%s",i)} print "";delete a}' input.txt
rozpadł dla łatwiejszego czytania, to może być samodzielny tak:
#!/usr/bin/awk -f
{
# Step through the line, assigning each character as a key.
# Repeated keys overwrite each other.
for(i=1;i<=length($0);i++) {
a[substr($0,i,1)]=1;
}
# Print items in the array.
for(i in a) {
printf("%s",i);
}
# Print a newline after we've gone through our items.
print "";
# Get ready for the next line.
delete a;
}
Oczywiście, ta sama koncepcja może być realizowane bardzo łatwo w czystej bash także:
#!/usr/bin/env bash
while read s; do
declare -A a
while [ -n "$s" ]; do
a[${s:0:1}]=1
s=${s:1}
done
printf "%s" "${!a[@]}"
echo ""
unset a
done < input.txt
Zauważ, że to zależy od bash 4, ze względu na tablicy asocjacyjnej. I ten jeden robi dostać rzeczy w oryginalnej kolejności, ponieważ bash ma lepszą pracę utrzymywania kluczy tablicy w kolejności niż awk.
Wydaje mi się, że masz rozwiązanie z użyciem sed
od Jose, choć wiąże się ono z kilkoma dodatkowymi parametrami. :)
Ostatnie wspomniane narzędzie to grep
. Jestem prawie pewien, że nie możesz tego zrobić w tradycyjnym grep, ale być może jakaś dzielna dusza może zbudować wariant perl-regexp (tj. grep -P
) używając -o
i lookarounds. Potrzebują więcej kawy niż teraz.
To jest krótsze! Czym są ':;' i 't' zrobić? – user1436187
@ user1436187 Dodano wyjaśnienie – 123
Przyjmuję to jako odpowiedź! – user1436187