OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Четверг, 17 Октябрь, 2019 06:15

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 15 ] 
Автор Сообщение
СообщениеДобавлено: Понедельник, 22 Март, 2010 01:07 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2316
Откуда: Россия, Томск
Подскажите, пожалуйста. Копался сегодня в Интернетах, не мог найти готовой реализации вот такой консольной программы под Windows:
Код:
MODULE Blank;

(* ------------------------------------------------------------------------
 * (c) 2010 by Alexander Iljin
 * ------------------------------------------------------------------------ *)

IMPORT In;

(** -----------------------------------------------------------------------
  * This console program returns 1 if a non-blank character was read from
  * StdIn.
  * ----------------------------------------------------------------------- *)

VAR
   ch: CHAR;
BEGIN
   In.Open;
   In.Char (ch);
   WHILE In.Done & (ch <= ' ') DO
      In.Char (ch);
   END;
   IF ~In.Done THEN
      HALT (1);
   END;
END Blank.

Пробовал grep, findstr, sfk - не получается. То ли я сегодня торможу, то ли что. Есть ли в природе утилита, которая бы подобное действие выполняла?

Общая задача - проверка непустоты сообщения в Subversion pre-commit hook (server-side). Другими словами, надо определить, есть ли в неком файле значимые символы (кроме пробелов, переводов строки, табуляции и прочего неотображаемого мусора). В шаблоне, поставляемом с Subversion, предлагается использовать grep "[a-zA-Z0-9]", но это, очевидно, не катит для русскоязычных сообщений. Пробовал расширить выражения до [a-zA-Z0-9а-яА-Я] - не срабатывает, скорее всего из-за разницы в кодировках между консолью и Subversion. Может быть, я что-то не знаю про регулярные выражения, или про стыковку кодировок подскажете?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 22 Март, 2010 14:50 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1538
Откуда: Беларусь, Минск
У меня имеется такое предположение.
Есть разные grep-ы. Некоторые, вроде, поддерживают отрицание. То есть, можно написать запрос, который семантически можно трактовать как "не что-то". И написать в запросе вместо "что-то" все пробельные символы.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 22 Март, 2010 14:58 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 909
Откуда: Киев
Может это подойдет. Чистит пробелы и табуляции, насчет других символов - не знаю.
Код:

REM some commands

CALL :BLANK %check_string%

REM some commands


GOTO :EOF

:BLANK
IF not "%1"=="" EXIT /b 1


Последний раз редактировалось Comdiv Понедельник, 22 Март, 2010 15:08, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 22 Март, 2010 15:08 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4512
Откуда: Россия, Орёл
Александр, Ваша утилита не подходит? Нужно именно регулярным выражением?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 22 Март, 2010 15:13 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2316
Откуда: Россия, Томск
Valery Solovey писал(а):
У меня имеется такое предположение.
Есть разные grep-ы. Некоторые, вроде, поддерживают отрицание. То есть, можно написать запрос, который семантически можно трактовать как "не что-то". И написать в запросе вместо "что-то" все пробельные символы.
Хорошо, пусть у нас есть конструкция [^...]. Как в командной строке передать туда символы перевода строки, возврата каретки, 0X?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 22 Март, 2010 15:36 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2316
Откуда: Россия, Томск
Евгений Темиргалеев писал(а):
Александр, Ваша утилита не подходит? Нужно именно регулярным выражением?
Подходит, и даже уже работает по назначению. Вопрос просто в том, как бы не плодить зоопарк утилит, а научиться пользоваться существующими. Пакет GNU-утилит у меня итак уже установлен, неужели же задача настолько нетипичная?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 22 Март, 2010 15:45 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2316
Откуда: Россия, Томск
Comdiv писал(а):
Может это подойдет. Чистит пробелы и табуляции, насчет других символов - не знаю.
Интересный вариант, спасибо. Вынудил посмотреть справку к CALL, узнал кое-что новое для себя. Проблема, однако, в том, что требуется проверить потенциально многострочный файл. Как это сделать? Оформить циклом?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 22 Март, 2010 16:13 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4512
Откуда: Россия, Орёл
Александр Ильин писал(а):
... требуется проверить потенциально многострочный файл. Как это сделать? Оформить циклом?
Вместо той "отдельной утилиты" (подпрограммы) воспользоваться Вашей :)


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 22 Март, 2010 16:26 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 909
Откуда: Киев
Для многострочного вывода можно посмотреть на следующий сценарий:
Код:
CALL :CHECK type test.txt

GOTO :EOF

:CHECK
FOR /F %%i IN ('%*') DO EXIT /b 1


вместо "type test.txt" пишите нужную команду, и ее вывод будет разобран FOR; если в нем будет хоть одна не пустая строка, выполнится EXIT /b 1


Последний раз редактировалось Comdiv Понедельник, 22 Март, 2010 16:35, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 22 Март, 2010 16:40 

Зарегистрирован: Пятница, 20 Июль, 2007 17:26
Сообщения: 698
Откуда: Псков
cat file|tr -d [:space:] |tr -d [:cntrl:] |wc -c


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 22 Март, 2010 16:47 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1538
Откуда: Беларусь, Минск
Александр Ильин писал(а):
Как в командной строке передать туда символы перевода строки, возврата каретки, 0X?
Не понятно, зачем воспринимать символ 0X как пробельный. Он же ведь не должен появляться в тексте в обычных случаях.

Вот вариант с sed, поскольку с grep отрицание у меня не работает.

cat test.txt | sed -e '/[^ \r\n\x0]/!d'


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 22 Март, 2010 17:20 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2316
Откуда: Россия, Томск
Александр Ильин писал(а):
Как это сделать? Оформить циклом?
Эврика!
Код:
:: Make sure that the log message contains some text.
set result=1
for /f "eol= " %%i in (%TMPFILE%) do set result=0
if %result% == 1 (
  echo Commits with empty log message are not allowed. >&2
)

del %TMPFILE% > NUL
exit %result%


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 22 Март, 2010 17:28 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2316
Откуда: Россия, Томск
Valery Solovey писал(а):
cat test.txt | sed -e '/[^ \r\n\x0]/!d'
Во, уже похоже на правду!
Тогда уж так: [^\x0- ], чтобы табуляции и прочий мусор учесть. Это, пожалуй, будет наиболее близко к озвученным требованиям.
Ещё, пожалуй cat не нужен: sed -e '/[^\x0- ]/!d' < test.txt


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 22 Март, 2010 17:42 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2316
Откуда: Россия, Томск
albobin писал(а):
cat file|tr -d [:space:] |tr -d [:cntrl:] |wc -c
Спасибо! Тоже отличный вариант. Почитал справку по tr и wc, буду иметь их в виду.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 22 Март, 2010 19:35 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2316
Откуда: Россия, Томск
Comdiv писал(а):
CALL :CHECK type test.txt
Понравилось, что просмотр файла прервётся как только будет найдена непустая строка (в моём предыдущем коде всегда весь файл просматривался целиком). Поэтому окончательный вариант у меня такой:
Код:
@echo off
set REPOS="%1"
set TXN="%2"
set TMPFILE=Log%RANDOM%.tmp

:: Make sure that the log message contains some text.
svnlook log -t %TXN% %REPOS% > %TMPFILE%
call :CheckBlank %TMPFILE%
set result=%errorlevel%
if %result% == 1 (
  echo Commits with empty log message are not allowed. >&2
)

del %TMPFILE% > NUL
exit %result%

:: Return 1 if %1 is a blank file, otherwise return 0
:CheckBlank
for /f "eol= " %%i in (%1) do exit /b 0
exit /b 1
Остановился на подходе с FOR потому, что вообще всё делается средствами интерпретатора CMD, без привлечения сторонних утилит.

Обращаю внимание на то, что без параметра "eol= " строки, начинающиеся с символа ";", считаются пустыми.

Данный файл именуется "pre-commit.bat" и помещается в каталог hooks любого репозитория Subversion, после чего попытка сделать коммит в данный репозиторий без описания (т.е. с пустым log message) прерывается с сообщением об ошибке "Commits with empty log message are not allowed." Помогает против случайного/преждевременного коммита и неопытных сотрудников.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 15 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2019, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB