греп дивної поведінки з однословними словами


10

Я видаляю слова із зупинки з тексту, приблизно використовуючи цей код

У мене є таке

$ cat file
file
types
extensions

$ cat stopwords
i
file
types

grep -vwFf stopwords file

Я очікую результату: extensions

але я отримую (я вважаю неправильним)

file
extensions

Це так, ніби слово fileбуло пропущено у файл зупинок. Тепер ось прохолодно трохи: якщо я змінити файл ігнорованих слів, шляхом зміни одного слова / букви iна першій лінії, в будь-який інший ASCii літери , крім f, i, l, e, то та ж команда Grep дає мені інший і правильний результат extensions.

Що тут відбувається і як це виправити?

Я використовую grep (BSD grep) 2.5.1-FreeBSD на базі Mac OSX GNU, версія 4.4.12 (1)


Можливо, ви хочете використовувати -xперемикач для регулярного вираження ліній замість -wслова? Однак я думаю, що -Fперемикач скасує будь-який з них, або навпаки.
jesse_b

grep (GNU grep) 3.1 працює, як ви очікуєте.
Hauke ​​Laging

Я це повторив. Інша дата: Якщо викріпити цей iшаблон другим, а не першим, він stopwordsтакож змінює поведінку.
JdeBP

Я не можу відтворити поведінку на OpenBSD 6.2 grepні з нативної, ні з GNU grep3.1.
Kusalananda

Відповіді:


13

Це помилка bsdgrep, що стосується змінної, яка відслідковує частину поточного рядка досі для сканування, яка перезаписується послідовними викликами до двигуна відповідних регулярних виразів, коли задіяно кілька шаблонів.

локальне виправлення

Ви можете подолати це певною мірою, не скориставшись -wопцією, яка спирається на цю змінну для правильної роботи і, таким чином, не працює, але замість цього використовуйте розширення регулярних виразів, які відповідають початку та кінці слів, роблячи ваш stopwordsфайл схожим:

\ <i \>
\ <файл \>
\ <типи \>

Цей спосіб вирішення також зажадає не використовувати цей -Fпараметр.

Зауважте, що задокументовані компоненти регулярних виразів [[:<:]]та [[:>:]]те, що re_formatкерівництво розповідає про вас, тут не працюватимуть. Це пояснюється тим, що в бібліотеці регулярних виразів, яка компілюється, bsdgrepувімкнено підтримку сумісності регулярних виразів GNU. Це ще одна помилка, яку, як повідомляється, виправлено.

виправлення обслуговування

Ця помилка була виправлена ​​на початку цього року. Виправлення ще не перетворило його на STABLE або RELEASE ароматизатори FreeBSD, але, як повідомляється, в СУЧАСНО.

Щоб отримати це у версії MacOS grep, що походить від FreeBSD bsdgrep, зверніться до Apple. ☺

Подальше читання


Приємно, і дякую за повідомлення про це вище за течією. Мені ця відповідь буде ще більш захоплюючою, якби вона цитувала баггі-код.
dhag

1

Цей код:

pl " Input data file data1 and stopwords file data2:"
head data1 data2

pl " Expected output:"
cat $E

pl " Results, grep:"
# grep -vwFf stopwords file
grep -vwFf data2 data1

pl " Results, cgrep:"
cgrep -x1 -vFf data2 data1

виробляє:

-----
 Input data file data1 and stopwords file data2:
==> data1 <==
file
types
extensions

==> data2 <==
i
file
types

-----
 Expected output:
extensions

-----
 Results, grep:
file
extensions

-----
 Results, cgrep:
extensions

У такій системі, як:

OS, ker|rel, machine: Apple/BSD, Darwin 16.7.0, x86_64
Distribution        : macOS 10.12.6 (16G29), Sierra
bash GNU bash 3.2.57

Більш детальна інформація про cgrep, доступна за допомогою пивоваріння та від sourceforge:

cgrep   shows context of matching patterns found in files (man)
Path    : ~/executable/cgrep
Version : 8.15
Type    : Mach-O64-bitexecutablex86_64 ...)
Home    : http://sourceforge.net/projects/cgrep/ (doc)

ура, др


тільки що отримав собі нову греп.
Тім

@Tim - Сподіваюся, ти вважаєш, що cregp є такою ж корисною, як і я. Швидкість тестів, які я зробив, приводить це приблизно нарівні з GNU grep, а функції "контексту / вікна" дуже корисні. Він також легко будується на системах Linux ... ура, drl
drl
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.