У меня есть файл, который выглядит так:
a: 0
a: 0
a: 0
a: 1
b: 1
c: 1
d: 1
e: 1
f: 1
a: 2
b: 2
c: 2
d: 2
e: 2
f: 2
a: 3
b: 3
c: 3
d: 3
e: 3
f: 3
c: 4
c: 4
c: 4
Я хочу захватить и вывести все строки a и c формы <a line><anything other than an a or c line><c line>, чтобы вывод выглядел так:
a: 1
c: 1
a: 2
c: 2
a: 3
c: 3
Обратите внимание, что ни строки a: 0 в начале, ни строки c: 4 в конце не захватываются, потому что они не следуют шаблону, который я упомянул. Также обратите внимание, что строки b между строками a и c удалены.
Я пытался сделать это с помощью поиска, используя pcregrep Bash, но пока не нашел решения. Есть идеи?
Спасибо!
Что вы пробовали? Какое это имеет отношение к bash? Где вы нашли, что bash обеспечивает pcregrep? Опубликуйте свои попытки, сделанные до сих пор
Почему в выводе есть пробелы между двумя строками?
@ПС. Я отредактировал свой оригинальный пост. Я упустил некоторую информацию раньше. Вы правы в том, что предложенное вами регулярное выражение решает то, что я изначально написал, поэтому я проголосовал.
@Inian Я обновил свой исходный пост, я упустил некоторую информацию. Что касается bash, я пишу команды pcregrep в оболочке bash на OS X (терминал). Примером того, что я пробовал до сих пор, является pcregrep -M '^a(?=(^b))^c' , где я пытаюсь сопоставить строку, начинающуюся с "a", которая имеет "b" строку перед ней и строку «c», а также включить только строки «a» и «c».
Вы, вероятно, хотите awk-решение, многострочное с grep быстро становится грязным.





Пытаться:
$ awk -F: '$1= = "a"{aline=$0} $1= = "c"{if (aline)print aline ORS $0 ORS; aline = ""}' file
a: 1
c: 1
a: 2
c: 2
a: 3
c: 3
По умолчанию awk читает по одной строке за раз.
-F:
Это говорит awk использовать : в качестве разделителя полей.
$1= = "a"{aline=$0}
Каждый раз, когда наблюдается строка a, сохраняйте строку в переменной aline.
$1= = "c"{if (aline)print aline ORS $0 ORS; aline = ""}
Каждый раз, когда наблюдается строка c, проверяем, есть ли у нас непустая aline. Если это так, выведите aline и текущую строку, разделенные символами новой строки. Кроме того, установите aline обратно на пустую строку.
Для тех, кто предпочитает, чтобы их команды распределялись по нескольким строкам:
awk -F: '
$1= = "a"{
aline=$0
}
$1= = "c"{
if (aline)
print aline ORS $0 ORS
aline = ""
}' file
$ sed -n '/^a/h; /^c/{x;/^a/{p;x;s/$/\n/;p};h}' file
a: 1
c: 1
a: 2
c: 2
a: 3
c: 3
-n
Это говорит sed ничего не печатать, если мы явно не попросим его об этом.
/^a/h
Всякий раз, когда у нас есть строка, начинающаяся с a, мы сохраняем ее в место для хранения.
/^c/{ x; /^a/{ p; x; s/$/\n/; p}; h}
Каждый раз, когда у нас есть строка, начинающаяся с c, мы:
Мы меняем (x) пространство шаблона с пространством удержания.
Если новое пространство шаблонов начинается с a, то мы печатаем (p) его и снова меняем местами (x), добавляем новую строку в конец нового пространства шаблонов (s/$/\n/) и печатаем (p) его.
Наконец, мы сохраняем текущее пространство шаблона (которое начинается с c) в пространство для хранения.
Спасибо! Я не использовал awk раньше, но я попробую использовать это.
зачем усложнять
pcre, вы пробовалиgrep -E '^[ac]'?