У меня есть этот файл:
sometext1{
string1
}
sometext2{
string2
string3
}
sometext3{
string4
string5
string6
}
Я хочу найти в этом файле определенную строку и распечатать все до этой строки до открытия {
и все после этой строки до закрытия }
. Я попытался добиться этого с помощью sed, но если я попытаюсь напечатать все в диапазоне, /{/,/string2/
например, sed напечатает это:
sometext1{
string1
}
sometext2{
string2
sometext3{
string4
string5
string6
}
Если я ищу строку «string2», мне нужен вывод:
sometext2{
string2
string3
}
Спасибо.
text-processing
sed
Rodrigo
источник
источник
grep -n '' <infile | sed ...
. Этиsed
команды будут нужны модифицирование; в частности, биты/
адреса,/
которые ищут^
якоря верхнего уровня. Таким образом, если вы использовали мой ответ, вероятно , можно сделать следующее :grep -n '' | sed 'H;/{$/h;/^[^:]*:}/x;/{\n.*PATTERN/!d'
. Все выходные строки будут иметь префикс с номерами строк исходного файла, за которыми следуют двоеточие, как1:sometext1{\n2:string1
и так далее.sed
будет фильтровать только то, что фильтрует раньше, за исключением того, что каждая строка вывода открывается с номером.Ответы:
Вот две команды. Если вам нужна команда, которая обрезает до последней
.*{$
строки в последовательности (как это делает @don_crisstied
), вы можете сделать:... который работает, добавляя каждую строку к
H
старому\n
пробелу после символа ewline, перезаписываяh
старый пробел для каждой совпадающей строки{$
, и заменяяh
старый и шаблонный пробел для каждой подходящей строки^}
- и тем самым сбрасывая свой буфер.Он печатает только строки , которые соответствуют а
{
затем\n
ewline , а затемPATTERN
в какой - то момент - и это только когда - либо произойдет сразу после буфера подкачки.Это исключает любые строки в серии
{$
совпадений до последнего в последовательности, но вы можете получить все эти включительно, такие как:То, что он делает, - это шаблон подстановки и
h
старые пробелы для каждой...{$.*^}.*
последовательности, добавляет все строки в последовательности кH
старому\n
пробелу после символаD
ewline и заменяет до первого встречающегося\n
символа ewline в пространстве образца для каждого цикла строки, прежде чем снова начинать с того, что осталось.Конечно, единственный раз, когда он получает
\n
ewline в пространстве шаблонов, это когда строка ввода совпадает^}
- конец вашего диапазона - и поэтому, когда он перезапускает скрипт в любом другом случае, он просто вытягивает следующую строку ввода в обычном режиме.Однако, когда он
PATTERN
находится в том же пространстве паттерна, что и электронная\n
линия, он печатает партию перед тем, как^}
снова перезаписать ее (чтобы он мог завершить диапазон и очистить буфер) .Учитывая этот входной файл (спасибо Дон) :
Первые отпечатки:
... а второй ...
источник
}
. Это может быть полезно для таких как ...open{\nsub;\n{ command; }\n}; close
- но я не уверен, что здесь происходит ...{...}
блоках? Если это так, и вы используете первое решение, то вы можете сделать это/{$/,/^}/H
в начале, а не простоH
. Но если вы также попробовали второе решение и все еще столкнулись с той же ошибкой, это вряд ли поможет, потому что это уже делает это. И не стоит сбрасывать со счетовed
. У Дона очень хороший ответ, и егоed
можно очень просто использовать для временных файлов буфера , что должно предотвратить переполнение буфера памяти.Вот решение с
ed
:это:
Предполагается, что
PATTERN
между каждой парой есть только одна строка,{
}
иначе вы получите дублированный вывод для каждой дополнительной строкиPATTERN
внутри одного и того же блока.Он будет работать для нескольких,
{
}
содержащих совпадение одной строки,PATTERN
например, для тестового файлаPATTERN
в двух разных разделах:Бег
выходы:
источник
С
pcregrep
:Или с GNU
grep
при условии, что входные данные не содержат байтов NUL:источник
где:
string4
-> Строка для сопоставленияt1.txt
-> содержит содержимое файла, указанное в запросеисточник
sed -n '/ string / p' filename
-n при добавлении в sed подавляет поведение sed по умолчанию, это утверждение может не дать вам именно то, что вы хотите, а просто сместить строку
источник