
Я хочу найти все последовательности, расположенные в алфавитном порядке в текстовом файле, без сортировки.
Пример: предположим, что текстовый файл выглядит следующим образом:
aedftg
wqof
abcdef
oufn
pqrs
aabcd
выход должен быть
abcdef
pqrs
также без повторяющихся символов, таких как aabcd
.
решение1
Один из вариантов, жестко запрограммированный для английского языка:
grep -ix 'a*b*c*d*e*f*g*h*i*j*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*z*' input
Кредит дляNinjaBearMonkeyдля изложения идеи, которая зарождалась в моей голове; я изменил регулярное выражение, чтобы разрешить повторяющиеся символы ( aabcc
).
Другой вариант:
Использование sort
для проверки порядка сортировки, специфичного для локали, является лучшим способом, так как вам не придется жестко кодировать алфавит.МайкДжонси сделал, это означает, что вам нужно разбить символы строки на отдельные строки. Я сделал это с помощью скрипта оболочки (используя современную оболочку, которая поддерживает расширение подстрок), чтобы избежать вызова sed, и который также использует sort
опцию -c для указания того, отсортирован ли уже ввод или нет:
while IFS= read -r line
do
for((i=0; i < ${#line}; i++))
do
printf '%s\n' "${line:i:1}"
done | sort -c 2>/dev/null && printf '%s\n' "$line"
done
Если sort
обнаруживается несоответствие, вывод выполняется в stderr, но нас интересует только код возврата, поэтому я пропускаю stderr.
Демонстрация с неанглийским вводом ( $
символы — это подсказки оболочки):
$ cat input
αβγα
αβγ
$ ./sorted2 < input
αβγ
$
решение2
Для полноты картины приведем awk
решение на основе , в котором обычные отношения шаблона и данных меняются местами:
awk 'BEGIN{ref="abcdefghijklmnopqrstuvwxyz"} ref ~ $0' file.txt
Это интерпретирует строки в файле как регулярные выражения, с которыми сопоставляется «справочная» строка отсортированных символов от a
до z
. Только если есть совпадение (что означает, что строка в строке является подстрокой a ... z
), строка будет напечатана.
решение3
perl -MPOSIX -Mopen=locale -lne '
print unless m{(.)(.)(?(?{strcoll($1, $2) < 0})(*FAIL))}' < file
Будут напечатаны строки, file
за исключением тех, которые содержат символ, который не следует за предыдущим в локали пользователя.
решение4
cat homework.txt | while read aline; do
stringORIG=$(echo -n "$aline" | sed 's/\(.\)/\1\n/g')
stringABC=$(echo -n "$aline" | sed 's/\(.\)/\1\n/g' | sort)
if [ "$stringORIG" == "$stringABC" ]; then
echo "$aline"
fi
done
.
abcdef
pqrs
ps... если вы не хотите использовать команду сортировки, вы можете преобразовать каждый символ в целое число и использовать оператор if для проверки того, что последний символ меньше следующего...