LINUX.ORG.RU

GREP поиск русских слов в xls, xlsx файлах

 


0

2

Добрый день!

Не могу понять, почему не работает команда для поиска русских слов в файлах

grep --include=\*.{xls,xlsx} -rnw . -e ‘text’

Когда текст на английском языке - всё работает супер

grep --include=\*.{xls,xlsx} -rnw . -e ‘текст’

А пытаюсь найти русский текст - не ищет, в чём может быть проблема?

grep (GNU grep) 3.11



Последнее исправление: arrogantworm (всего исправлений: 3)
Ответ на: комментарий от firkax

Так тоже ничего не дает

LANG=ru_RU.CP1251

LC_CTYPE=«ru_RU.CP1251»

LC_NUMERIC=«ru_RU.CP1251»

LC_TIME=«ru_RU.CP1251»

LC_COLLATE=«ru_RU.CP1251»

LC_MONETARY=«ru_RU.CP1251»

LC_MESSAGES=«ru_RU.CP1251»

LC_PAPER=«ru_RU.CP1251»

LC_NAME=«ru_RU.CP1251»

LC_ADDRESS=«ru_RU.CP1251»

LC_TELEPHONE=«ru_RU.CP1251»

LC_MEASUREMENT=«ru_RU.CP1251»

LC_IDENTIFICATION=«ru_RU.CP1251»

LC_ALL=

aw@aw-laptop:/run/media/aw/Samsung_T5/Новая папка (2)$ grep –include=*.{xls,xlsx} -rnw . -e ‘БОКАЛ’

aw@aw-laptop:/run/media/aw/Samsung_T5/Новая папка (2)$ env LANG=ru_RU.CP1251 grep –include=*.{xls,xlsx} -rnw . -e ‘БОКАЛ’

arrogantworm
() автор топика
Ответ на: комментарий от arrogantworm

Надо не локаль ставить а строку для поиска вводить в этой кодировке. Поменяй кодировку в эмуляторе терминала, которым пользуешься.

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

Если надо автоматически искать по строке, которую тебе же кто-то дал в utf8, то её надо сначала сконвертировать в 1251 с помощью iconv.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 3)
Ответ на: комментарий от iron

Файлов больше 1000, думаю вот может скрипт на питоне написать

с переводом кодировки тоже что-то не сработало, хотя я может сделал что не так

grep –include=*.{xls,xlsx} -rnw . -e ‘echo ‘БОКАЛ’ | iconv -c -f UTF-8 -t WINDOWS-1251’

arrogantworm
() автор топика
Ответ на: комментарий от arrogantworm

Разметь код как код а то непонятно какие там кавычки.

А вообще на всякий случай открой найди как оно выглядит в файле, вдруг там не cp1251. Например сделай файл со строкой abcабвabc, найди её grep-ом по англ части и сделай hexdump -C на то что нашлось.

firkax ★★★★★
()

Когда текст на английском языке - всё работает супер

А ты уверен? xlsx — это по сути zip-архив с xml-ками, т. е. бинарный файл, причём пожатый бинарный файл. Давно ли grep умеет распаковывать архивы, чтобы искать в них текст?? Ты пробовал искать что-нибудь более осмысленное, чем ‘text’?

xls – тоже бинарный формат, грепать его — не слишком удачная идея. Но если этот формат не использует сжатие (я не в курсе), то найти в нём текст грепом может быть и получится. А может, и нет.

Чтобы что-то грепать в xls и xlsx файлах, надо для начала сконвертировать их в текст.

P. S. Глянул щас на образчик xls файла. Похоже, что он без сжатия. Но в зависимости от ячейки текст может быть сохранён или в ASCII (или, может, в ISO 8859-1) (если только латинские буквы), или в UTF-16 (если есть русские буквы). Поэтому из консоли грепать русский текст в xls занятие нетривиальное. Конверторы кодировок типа iconv сконвертировать xls скорее всего не смогут, т. к. это не текст а бинарный файл, поэтому надо перекодировать саму строку поиска, что муторно (и не поможет в случае xlsx). Проще найти конвертилку xls и xlsx в текстовый вид, а потом уж и грепать.

P. P. S. Советов тебе надавали, конечно, огонь… рукалицо.jpg

debugger ★★★★★
()
Последнее исправление: debugger (всего исправлений: 3)
Ответ на: комментарий от debugger

Сконвертировать таблицы в текст оказалось тоже нетривиально. libreoffice --convert-to txt *.xls{,x} не ругается, возвращает 0 (успех), но ничего не делает. libreoffice --convert-to csv *.xls{,x} конвертирует, но только первую страницу. Если в таблице было больше одной страницы, то упс. Хорошо работает libreoffice --convert-to html *.xls{,x} — конвертирует все страницы. html уже можно грепать, поскольку это текстовый формат. При этом возможны ложные срабатывания грепа на хтмльные теги и атрибуты, на всякий текст в голове (<head>...</head>). Если это проблема, то нужно ещё одно конвертирование из html в palin text, но это уже просто.

debugger ★★★★★
()
Ответ на: комментарий от debugger

Сработало!

echo 'БОКАЛ' | iconv -c -f utf8 -t=UTF-16
���
grep --include=\*.{xls,xlsx} -rnw . -e '���'

Вывод:

grep: ./1.xlsx: binary file matches
grep: ./2.xlsx: binary file matches
grep: ./3.xlsx: binary file matches
grep: ./4.xlsx: binary file matches
grep: ./5.xlsx: binary file matches
grep: ./папка/2.xlsx: binary file matches

Вопрос теперь, как в одной строке конвертировать текст для поиска в UTF-16 и его же и запульнуть в grep?

Спасибо за наводку! UTF-16 там, оказывается

arrogantworm
() автор топика
Ответ на: комментарий от arrogantworm

Вопрос теперь, как в одной строке конвертировать текст для поиска в UTF-16 и его же и запульнуть в grep?

man bash, look for $(...).

Не майся ерундой. Это не будет работать для xlsx и может не работать (или работать плохо, например, выдавать ложные срабатывания) для xls. xls — бинарный формат, без понимания что и как там хранится результат будет случайным. Например, удалишь страницу таблицы, эксель пометит её как удалённую, а из файла удалять её не будет — и греп тебе скажет что в файле есть вхождения искомой строки, а откроешь файл в экселе — и вхождений не найдёшь. Или наоборот. Или набор кодировок может оказаться шире чем ISO 8859-1 и UTF-16. Или ещё что. xls — тёмный ящик.

Кстати, ты понимаешь, что если в xls файле будет не слово БОКАЛ а Бокал или бокал, то греп тебе ничего не найдёт и -i не поможет?

Хочешь надёжного результата — делай, как я сказал: libreoffice --convert-to html, потом грепай.

Впрочем, мне плевать, дело твоё.

debugger ★★★★★
()
Последнее исправление: debugger (всего исправлений: 2)
Ответ на: комментарий от arrogantworm

Сработало!

Я очень сильно сомневаюсь.

$ echo 'БОКАЛ' | iconv -c -f utf8 -t=UTF-16 > iconv.out

$ echo 'БОКАЛ' | iconv -c -f utf8 -t=UTF-16
���

$ echo '���' > echo.out

$ ll *.out
-rw-r--r--. 1 vdb vdb 10 Jul 27 01:05 echo.out
-rw-r--r--. 1 vdb vdb 14 Jul 27 01:05 iconv.out

$ hexdump iconv.out 
0000000 feff 0411 041e 041a 0410 041b 000a     
000000e

$ hexdump echo.out 
0000000 bfef efbd bdbf bfef 0abd               
000000a

$ iconv -f UTF-16 -t UTF-8 < iconv.out 
БОКАЛ

$ iconv -f UTF-16 -t UTF-8 < echo.out 
뿯붿뿯ઽ

Теперь вопрос: почему вывод в файл поддаётся обратной перекодировке, а копи-паста с экрана — нет? Следующий вопрос: что же ты на самом деле искал и что нашёл?

debugger ★★★★★
()
Последнее исправление: debugger (всего исправлений: 2)