Bash / Sed: Concat несколько строк плюс есть пробелы для сублиний - PullRequest
2 голосов
/ 09 февраля 2011

Я хочу разобрать Makefiles, содержащие такие строки:

FILES=file1.c \
      file2.c \
      file3.c \

Теперь я хочу разобрать этого зверя, чтобы получить такой результат:

FILES=file1.c file2.c file3.c

Означает, что он должен объединить всю строку в одну строку и поглотить ведущие пробелы. Мне уже удалось объединить строки, используя этот вызов sed:

sed -e ':loop;/\\$/N;s/\\\n/ /;t loop'

, что приводит к

FILES=file1.c      file2.c      file3.c

Но пока не удалось также съесть ведущие пробелы для строки 2 и строки 3 моего примера.

Спасибо за любую помощь,

Roland

Кстати: я использую GNU sed версии 4.1.5 здесь.

Ответы [ 4 ]

2 голосов
/ 09 февраля 2011

Мне кажется, это работает:

sed -e ':loop;/\\$/N;s/\\\n/ /;t loop' -e 's/ \+/ /g' < Makefile

Спасибо Деннису Уильямсону за указание на то, что вам не нужно -r, если вы сбежите с + с \. Он также отмечает, что это не работает, когда последний символ перед концом файла равен \. Однако в реальном примере это маловероятно, поскольку бессмысленно продолжать линию, если после этого ничего не происходит. например он отлично работает с:

FILES=file1.c \
      file2.c \
      file3.c

... вместо.

Я проверял это только с GNU sed 4.2.1 - боюсь, у меня нет более ранней версии.

1 голос
/ 09 февраля 2011

Попробуйте это:

sed -e ':loop;/\\$/N;s/\\\n/ /;s/ \+/ /g;t loop'

Дополнительная s/ \+/ /g находит всю последовательность нескольких пробелов в строке и заменяет их одним пробелом.

0 голосов
/ 09 февраля 2011

Сжатие пробела легче всего выполнить, отправив вывод в tr:

... | tr -s ' '

В этом случае это (вероятно) не будет работать, потому что первые пробелы, скорее всего, являются вкладками, поэтому вы можете сделать:

... | tr '\t' ' ' | tr -s ' '

или просто сделайте все это в perl:

perl -00 -pe 's/\s*\\\n\s*/ /sg'

Это сжимает все пробелы вокруг продолжения строки в один пробел, поэтому лишние пробелы вдали от новой строки не будут изменены, а пустые строки после символа продолжения будут использованы, что, вероятно, нежелательно. Кроме того, режим slurp не всегда подходит, поэтому, возможно, вы предпочтете:

perl -wpe 's/^\s*// if $v; $v = s/\s*\\\n/ /g'
0 голосов
/ 09 февраля 2011

Рубин (1,9 +)

ruby -ne '$_.gsub!(/\\\n/,""); print $_.gsub(/\s+/," ")' file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...