Используйте эту команду, чтобы решить эту проблему:dnf update --nogpgcheck
A (в основном-)sed
решение:
cat "$@" |
tr -cs -- '._[:alpha:]' '[\n*]' |
sed -n -e 'h; :ms' \
-e 'p; :ss' \
-e 's/\([[:lower:]]\)[[:upper:]][[:lower:]]*$/\1/p; t ss' \
-e 's/\([[:lower:]]\)[[:upper:]][[:upper:]]*$/\1/p; t ss' \
-e 's/\([[:upper:]]\)[[:upper:]][[:lower:]]\+$/\1/p; t ss' \
-e 's/[._][[:alpha:]][[:lower:]]*$//p; t ss' \
-e 's/[._][[:upper:]]\+$//p; t ss' \
-e 'g' \
-e 's/^[[:upper:]]\?[[:lower:]]\+\([[:upper:]]\)/\1/; t mw' \
-e 's/^[[:upper:]]\+\([[:upper:]][[:lower:]]\)/\1/; t mw' \
-e 's/^[[:alpha:]][[:lower:]]*[._]//; t mw' \
-e 's/^[[:upper:]]\+[._]//; t mw' \
-e 'b' \
-e ':mw; h; b ms'
Алгоритм
for each compound word (e.g., “FOO_BAR_test”) in the input
do
repeat
print what you’ve got
repeat
remove a small word from the end (e.g., “FOO_BAR_test” → “FOO_BAR”) and print what’s left
until you’re down to the last one (e.g., “FOO_BAR_test” → “FOO”)
go back to what you had at the beginning of the above loop
and remove a small word from the beginning
(e.g., “FOO_BAR_test” → “BAR_test”)... but don’t print anything
until you’re down to the last one (e.g., “FOO_BAR_test” → “test”)
end for loop
Детали:
cat "$@"
является UUOC. Обычно я избегаю этого; вы можете сделать tr args < file
, но вы не можете напрямую передавать несколько файлов в tr
. tr -cs -- '._[:alpha:]' '[\n*]'
разрывает строку со многими составными словами в отдельные строки; например., I_amAManTest you_haveAHouse FOO_BAR_test
становится I_amAManTest
you_haveAHouse
FOO_BAR_test
поэтому sed может обрабатывать одно составное слово за раз. sed -n
— автоматически ничего не печатать; печатать только по команде. -e
указывает, что следующее выражение e является частью сценария sed. h
— скопировать пространство паттерна в пространство удержания. :ms
— метка (Основной контур Старт)p
— напечатать :ss
— метка (Старт вторичного контура)s/\([[:lower:]]\)[[:upper:]][[:lower:]]*$/\1/p; t ss
— изменяет «nTest» на «n». s/\([[:lower:]]\)[[:upper:]][[:upper:]]*$/\1/p; t ss
— меняет «mOK» на «m». s/\([[:upper:]]\)[[:upper:]][[:lower:]]\+$/\1/p; t ss
— меняет «AMan» на «A». s/[._][[:alpha:]][[:lower:]]*$//p; t ss
— удаляет «_утра» (заменяет его ничем ). s/[._][[:upper:]]\+$//p; t ss
— удаляет «_BAR» (заменяет его ничем ). g
— скопировать пространство удержания в пространство шаблона (вернуться к тому, что у вас было в начале цикла выше ). s/^[[:upper:]]\?[[:lower:]]\+\([[:upper:]]\)/\1/; t mw
— изменяет «amA» на «A» и «ManT» на «T». s/^[[:upper:]]\+\([[:upper:]][[:lower:]]\)/\1/; t mw
— меняет «АМа» на «Ма». s/^[[:alpha:]][[:lower:]]*[._]//; t mw
— удаляет «я _» и «ты _» (заменяет их ничем ). s/^[[:upper:]]\+[._]//; t mw
— удаляет «FOO _» (заменяет его ничем ).b
— ветка (перейти )в конец скрипта sed; т. е. выйти из сценария sed. :mw
— метка для основной петли Wrap -вверх. h
— скопировать пространство паттерна в пространство удержания, чтобы настроиться на следующую итерацию основного цикла. b ms
— перейти в начало основного цикла. Он производит запрошенный вывод. К сожалению, это ставит его в другом порядке. Возможно, я могу это исправить, если это важно.
$ echo "I_amAManTest you_haveAHouse FOO_BAR_test" |./myscript
I_amAManTest
I_amAMan
I_amA
I_am
I
amAManTest
amAMan
amA
am
AManTest
AMan
A
ManTest
Man
Test
you_haveAHouse
you_haveA
you_have
you
haveAHouse
haveA
have
AHouse
A
House
FOO_BAR_test
FOO_BAR
FOO
BAR_test
BAR
Test
Лучше всего, вероятно, найти модуль токенизатора для perl. Grep не может сделать это без нескольких прогонов, вероятно, для этого потребуется-P
(PCRE ).
Вот частичное решение без каких-либо модулей perl:
while (<>) {
my $n = 1;
while (/(\S+)/g) {
printf "// outputting whitespace-separated word %d\n", $n++;
my $whole = $1;
while ($whole =~ /([a-zA-Z0-9][a-z]*+)/g) {
print "$1\n";
}
print "$whole\n"; # whole space-delimited tokens
}
}
Это считывает ввод из стандартного ввода или файлов, по одной строке за раз. $n
— это счетчик слов для печатного комментария, затем мы перебираем слова (, обозначенные пробелами, таким образом, регулярное выражение /(\S+)/g
глобально соответствует последовательным не -белым -символам пробела ). Внутри каждого слова мы перебираем части токена, используя ([a-zA-Z0-9][a-z]*+)
, все совпадения которых начинаются с цифр или букв, за которыми следует ноль или более строчных букв.(*+
похож на *
с отключенным откатом для защиты от РеДоС). После того, как мы напечатаем все совпадающие токены в слове, мы напечатаем все слово.
Вы запускаете это как perl solution.pl intput.txt
или встраиваете как:
$ echo "I_amAManTest you_haveAHouse FOO_BAR_test.model" |perl solution.pl
// outputting whitespace-separated word 1
I
am
A
Man
Test
I_amAManTest
// outputting whitespace-separated word 2
you
have
A
House
you_haveAHouse
// outputting whitespace-separated word 3
F
O
O
B
A
R
test
model
FOO_BAR_test.model
Обратите внимание, что здесь отсутствуют составные -подэлементы слов.
Также обратите внимание, что ваш запрос I_AmAMan
на анализ как I
, Am
, A
, Man
конфликтует с вашим запросом на FOO_BAR
на анализ в FOO
, BAR
, а не F
, O
, O
, B
... как в приведенном выше коде. (Возможно, лучшим примером будет :, чем должно стать I_AmOK
? Три униграммы или четыре?)
Вот начало, вам просто нужно помассировать его, как только вы выясните свои требования к строкам, содержащим смесь букв верхнего и нижнего регистра, и распечатать вывод в любом порядке, который вы показываете в своем вопросе:
$ cat tst.awk
{
for (wordNr=1; wordNr<=NF; wordNr++) {
delete ngrams
word = $wordNr
ngrams[word]
print "word", word
numUndSeps = split(word,undSeps,/_/)
for (undSepNr=1; undSepNr<=numUndSeps; undSepNr++) {
undSep = undSeps[undSepNr]
ngrams[undSep]
print "undSep", undSep
numDotSeps = split(undSep,dotSeps,/[.]/)
for (dotSepNr=1; dotSepNr<=numDotSeps; dotSepNr++) {
dotSep = dotSeps[dotSepNr]
ngrams[dotSep]
print "dotSep", dotSep
while ( match(dotSep,/[[:upper:]]+[^[:upper:]]+/) ) {
camel = substr(dotSep,RSTART,RLENGTH)
dotSep = substr(dotSep,RSTART+RLENGTH)
ngrams[camel]
print "camel", camel
}
}
}
print "-----------"
for (ngram in ngrams) {
print ngram
}
print "###########"
}
}
.
$ awk -f tst.awk file
word I_amAManTest
undSep I
dotSep I
undSep amAManTest
dotSep amAManTest
camel AMan
camel Test
-----------
Test
amAManTest
I_amAManTest
I
AMan
###########
word you_haveAHouse
undSep you
dotSep you
undSep haveAHouse
dotSep haveAHouse
camel AHouse
-----------
you
you_haveAHouse
haveAHouse
AHouse
###########
word FOO_BAR_test.model
undSep FOO
dotSep FOO
undSep BAR
dotSep BAR
undSep test.model
dotSep test
dotSep model
-----------
model
FOO
FOO_BAR_test.model
test.model
BAR
test
###########