Как можно объединить все строки, которые заканчиваются символом обратной косой черты?

Я ответ второго gabe. (мой комментарий является слишком длинным, таким образом, я отправляю как ответ).

Если у Вас нет узкоспециализированной цели (например, встроенные машины, строгое профилирование безопасности), я не вижу практического преимущества для компиляции Вашего собственного ядра кроме видеть, как это сделано. Путем методического рассмотрения опций наблюдения то, как они взаимодействуют друг с другом для создания системы, является отличным способом понять, как система работает. Удивительно, что Вы узнаете, когда Вы пытаетесь удалить компоненты, которые, кажется, не имеют цели для задач, которые Вы пытаетесь выполнить.

Предупредите однако - почему спрыгивающий от кроличьей норы является, несомненно, волнующим, она высосет назад больше ночей и выходных, чем Вы думали возможные!

37
12.02.2019, 15:44
9 ответов

более короткое и более простое sed решение:

sed  '
: again
/\\$/ {
    N
    s/\\\n//
    t again
}
' textfile

или острота при использовании GNU sed:

sed ':x; /\\$/ { N; s/\\\n//; tx }' textfile
28
27.01.2020, 19:36
  • 1
    хороший... Я initally посмотрел на это и не мог понять это (так это wen't в также твердую корзину)..., но после всестороннего взгляда на ответ Gilles (который взял вполне вдоль времени), у меня был другой взгляд на Ваш ответ, и выглядело удивительно понятным, что я думаю, что начинаю понимать sed :)... Вы добавляете каждую строку непосредственно к пространству шаблона, и когда "обычно законченная" строка приходит, все пространство шаблона проваливается и автоматическая печать (потому что нет никакой-n опции)... аккуратный!.. Решение +1 –  Peter.O 24.05.2011, 19:27
  • 2
    @fred: спасибо я думаю, что начинаю понимать sed также, он предлагает хорошие инструменты для многострочного редактирования, но как к путанице их для получения то, в чем Вы нуждаетесь, не просто, ни удобочитаемость является в вершине... альтом –  neurino 25.05.2011, 10:21
  • 3
    Остерегайтесь окончаний строки DOS, иначе. возвраты каретки или \r! –  user77376 28.11.2016, 12:01

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

perl -p -e 's/\\\n//'
19
27.01.2020, 19:36
  • 1
    , короткий и простой, мне нравится этот один +1, И он не попросил sed, или установка awk explicitely –  rudolfson 28.06.2017, 18:06

Вот awk решение. Если концы строки с a \, разделите обратную косую черту и распечатайте строку без завершения новой строки; иначе распечатайте строку с завершающейся новой строкой.

awk '{if (sub(/\\$/,"")) printf "%s", $0; else print $0}'

Это находится также не слишком плохо в sed, хотя awk, очевидно, более читаем.

18
27.01.2020, 19:36

Это не ответ как таковой. Это - второстепенный вопрос о sed.

А именно, я должен был взять Gilles sed управляйте независимо, чтобы часть частью поняла это... Я начал писать некоторые записки на нем и затем думал, что это может быть полезно здесь для кого-то...

таким образом, здесь это... sed сценарий жабр в зарегистрированном формате:


#!/bin/bash
#######################################
sed_dat="$HOME/ztest.dat"
while IFS= read -r line ;do echo "$line" ;done <<'END_DAT' >"$sed_dat"
foo bar \
bash \
baz
dude \
happy
yabba dabba 
doo
END_DAT

#######################################
sedexec="$HOME/ztest.sed"
while IFS= read -r line ;do echo "$line" ;done <<'END-SED' >"$sedexec"; \
sed  -nf "$sedexec" "$sed_dat"

  s/\\$//        # If a line has trailing '\', remove the '\'
                 #    
  t'Hold-append' # branch: Branch conditionally to the label 'Hold-append'
                 #         The condition is that a replacement was made.
                 #         The current pattern-space had a trailing '\' which  
                 #         was replaced, so branch to 'Hold-apend' and append 
                 #         the now-truncated line to the hold-space
                 #
                 # This branching occurs for each (successive) such line. 
                 #
                 # PS. The 't' command may be so named because it means 'on true' 
                 #     (I'm not sure about this, but the shoe fits)  
                 #
                 # Note: Appending to the hold-space introduces a leading '\n'   
                 #       delimiter for each appended line
                 #  
                 #   eg. compare the hex dump of the follow 4 example commands:  
                 #       'x' swaps the hold and patten spaces
                 #
                 #       echo -n "a" |sed -ne         'p' |xxd -p  ## 61 
                 #       echo -n "a" |sed -ne     'H;x;p' |xxd -p  ## 0a61
                 #       echo -n "a" |sed -ne   'H;H;x;p' |xxd -p  ## 0a610a61
                 #       echo -n "a" |sed -ne 'H;H;H;x;p' |xxd -p  ## 0a610a610a61

   # No replacement was made above, so the current pattern-space
   #   (input line) has a "normal" ending.

   x             # Swap the pattern-space (the just-read "normal" line)
                 #   with the hold-space. The hold-space holds the accumulation
                 #   of appended  "stripped-of-backslah" lines

   G             # The pattern-space now holds zero to many "stripped-of-backslah" lines
                 #   each of which has a preceding '\n'
                 # The 'G' command Gets the Hold-space and appends it to 
                 #   the pattern-space. This append action introduces another
                 #   '\n' delimiter to the pattern space. 

   s/\n//g       # Remove all '\n' newlines from the pattern-space

   p             # Print the pattern-space

   s/.*//        # Now we need to remove all data from the pattern-space
                 # This is done as a means to remove data from the hold-space 
                 #  (there is no way to directly remove data from the hold-space)

   x             # Swap the no-data pattern space with the hold-space
                 # This leaves the hold-space re-initialized to empty...
                 # The current pattern-space will be overwritten by the next line-read

   b             # Everything is ready for the next line-read. It is time to make 
                 # an unconditional branch  the to end of process for this line
                 #  ie. skip any remaining logic, read the next line and start the process again.

  :'Hold-append' # The ':' (colon) indicates a label.. 
                 # A label is the target of the 2 branch commands, 'b' and 't'
                 # A label can be a single letter (it is often 'a')
                 # Note;  'b' can be used without a label as seen in the previous command 

    H            # Append the pattern to the hold buffer
                 # The pattern is prefixed with a '\n' before it is appended

END-SED
#######
3
27.01.2020, 19:36

Еще один общий инструмент командной строки был бы ed, который по умолчанию изменяет оперативные файлы и поэтому оставляет полномочия файла неизмененными (для получения дополнительной информации о ed посмотрите файлы Редактирования с текстовым редактором редактора из сценариев),

str='
foo bar \
bash 1 \
bash 2 \
bash 3 \
bash 4 \
baz
dude \
happy
xxx
vvv 1 \
vvv 2 \
CCC
'

# We are using (1,$)g/re/command-list and (.,.+1)j to join lines ending with a '\'
# ?? repeats the last regex search.
# replace ',p' with 'wq' to edit files in-place
# (using Bash and FreeBSD ed on Mac OS X)
cat <<-'EOF' | ed -s <(printf '%s' "$str")
H
,g/\\$/s///\
.,.+1j\
??s///\
.,.+1j
,p
EOF
2
27.01.2020, 19:36

Можно использовать cpp, но он продолжает некоторые пустые линии, где он объединил вывод и некоторое введение, которое я удаляю с sed - возможно, он может быть сделан с cpp-флагами и опциями также:

echo 'foo bar \
bash \
baz
dude \
happy' | cpp | sed 's/# 1 .*//;/^$/d'
foo bar bash baz
dude happy
-1
27.01.2020, 19:36
  • 1
    Вы уверенный cpp решение? В Вашем примере echo со строкой в двойных кавычках уже выводы выправили текст, таким образом, cpp бессмысленно. (Это также относится к Вашему sed код.), Если Вы помещаете строку в одинарные кавычки, cpp просто удаляет обратные косые черты, но не связывает строки. (Конкатенация с cpp работал бы, если бы не будет никакого пространства перед обратными косыми чертами, но затем к отдельным словам присоединились бы без разделителей.) –  manatwork 22.05.2012, 12:18
  • 2
    @manatwork: Outsch!:) Я был удивлен, что команда sed работала, но конечно, это не была команда sed, но сам удар интерпретирует разрыв строки обратной косой черты как продолжение предыдущей строки. –  user unknown 22.05.2012, 14:41
  • 3
    Используя cpp как этот все еще не связывает строки для меня. И использование sed является определенно ненужным. Использовать cpp -P: “-P Поколение запрещения linemarkers в выводе от препроцессора”. – укомплектовывают cpp –  manatwork 22.05.2012, 14:57
  • 4
    Вашу команду, не работает на меня: cpp: “-P: No such file or directory cpp: warning: '-x c' after last input file has no effect cpp: unrecognized option '-P:' cpp: no input files A cpp --version показывает cpp (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3 - что? Ubuntu исправляет cpp? Почему? Я ожидал бы читать GNU... –  user unknown 22.05.2012, 15:14
  • 5
    Интересный. Ubuntu cpp действительно связывает строки и оставляет некоторые пробелы. Еще более интересный, та же версия, 4.4.3-4ubuntu5.1 здесь, принимает -P. Однако это только устраняет linemarkers, пустые строки остаются. –  manatwork 22.05.2012, 15:38
  • 6
    Интересный. Ubuntu cpp действительно связывает строки и оставляет некоторые пробелы. Еще более интересный, та же версия, 4.4.3-4ubuntu5.1 здесь, принимает -P. Однако это только устраняет linemarkers, пустые строки остаются. –  manatwork 22.05.2012, 15:38

Версия для Mac, основанная на решении @Giles, будет выглядеть следующим образом

sed ':x
/\\$/{N; s|\\'$'\\n||; tx
}' textfile

Где основное различие заключается в том, как представлены новые строки, и объединение любых дальнейших строк в одну разрывает ее

1
27.01.2020, 19:36

Простое (r )решение, которое загружает весь файл в память:

sed -z 's/\\\n//g' file                   # GNU sed 4.2.2+.

Или еще короткий, который работает с пониманием (вывода )строк (синтаксиса GNU):

sed ':x;/\\$/{N;bx};s/\\\n//g' file

На одной строке (Синтаксис POSIX):

sed -e :x -e '/\\$/{N;bx' -e '}' -e 's/\\\n//g' file

Или используйте awk (, если файл слишком велик и не помещается в памяти):

awk '{a=sub(/\\$/,"");printf("%s%s",$0,a?"":RS)}' file
1
27.01.2020, 19:36

Использование того факта, что readв оболочке интерпретирует обратную косую черту при использовании без-r:

$ while IFS= read line; do printf '%s\n' "$line"; done <file
foo bar bash baz
dude happy

Обратите внимание, что это также интерпретирует любой другой обратный слэш в данных.

2
27.01.2020, 19:36

Теги

Похожие вопросы