Я бы немного переработал скрипт, чтобы обрабатывать комментарии #
и //
самостоятельно. С комментариями /* … */
вам придется иметь дело с однострочными и многострочными вариантами отдельно. Я также использовал бы обозначение [[:space:]]
для выделения пробелов или табуляций. Я предпочитаю избегать обратной косой черты (отвращение, вызванное работой с troff
во времена моей юности - если вам никогда не требовалось 16 обратных косых черт подряд, чтобы получить желаемый эффект, вы недостаточно пострадали), поэтому я использую \%…%
, чтобы выбрать %
символ в качестве маркера поиска вместо /
(что означает, что нет необходимости экранировать косые черты в шаблоне с обратной косой чертой sh), и я использую [*]
вместо \*
. Запись { p; d; }
печатает текущую строку, а затем удаляет ее и переходит на следующую строку. (Использование n
добавляет следующую строку к текущей строке; это не то, что вам нужно.). Вторая точка с запятой не требуется для GNU sed
, но для BSD (macOS) sed
. Пробелы в этих скобках являются необязательными, но облегчают чтение.
Если сложить это вместе, у вас может быть spaces.sed
, например:
#!/bin/sed -f
# Comments with a #
/#/ { p; d; }
# Comments with //
\%//% { p; d; }
# Single line /* ... */ comments
\%/[*].*[*]/% { p; d; }
# Multi-line /* ... */ comments
\%/[*]%,\%[*]/% { p; d; }
s/\([^[:space:]]\)[[:space:]]\{2,\}/\1 /g
В ваших данных примера (спасибо, что включили это!), это производит:
/** spa.txt text
date : some date
hih+jjhh jgjg
if ( hjh>=hjhjh )
y **/
# this is a comment
// this is a comment
lines begins here ;
/****** this line is comment ****/
some more lines
// again comment
more lines words
/** again multi line co
mmment it
comment line
follows till here**/
file ends
Это выглядит так, как вы хотели.
Ограничения
Он не удаляет несколько пробелов в начало строки.
the leading blanks are not removed.
Если у вас есть строка с несколькими пробелами и //
или #
, несколько пробелов остаются:
these spaces // survive
so do # these
Если у вас есть несколько однострочных комментариев в одной строке, между ними не будет пробелов:
/* these */ spaces are not /* removed */
Если у вас есть однострочный комментарий и начало многострочного комментария на одной строке, многострочный комментарий не заметен. Точно так же, если у вас есть многострочный комментарий, который заканчивается строкой, а после него начинается однострочный комментарий, то если между концом одного комментария и началом следующего есть несколько пробелов, они не обработано.
/* this */ is not /* handled
very well */ nor are these /* spaces */
Это не касается тонкостей backsla sh -newline в середине символа начального или конечного комментария, а также backsla sh - перевод строки в конце комментария //
. Только мертвые программы (или программисты) дают такие комментарии, так что это не должно быть реальной проблемой. К счастью, вы не пишете компилятор; те имеют дело с ерундой. И не начинайте меня с триграфов!
Он не обрабатывает комментируемые последовательности внутри строк (или константы из нескольких символов):
"/* this is not a comment */"
'/*', ' ', '*/'
Тем не менее, большинство из этих проблем достаточно тонкие, так что вы, вероятно, в порядке, не решая их. Если вам нужно разобраться с ними, вам нужна программа, а не скрипт sed
(при условии, что вы цените свое здравомыслие).