Это было некоторое время, так как я оставил minimalisting менеджеры окон как fluxbox/openbox и такой, но здесь являюсь некоторыми подсказками, которые я вспоминаю:
Можно на самом деле видеть, какой код клавиши определенное сочетание клавиш повышается с помощью xev (1)
Можно использовать использование xmodmap (1) для привязки определенных кодов клавиши с X событиями.
Посмотрите взгляд на страницы справочника для xev и xmodmap ;)
Укажите awk, что нужно печатать между двумя разделителями. В частности:
awk '/\*{4,}/,/<np>/' file
Это также напечатает строки, содержащие разделители, поэтому вы можете удалить их с помощью:
awk '/\*{4,}/,/<np>/' file | tail -n +2 | head -n -1
В качестве альтернативы вы можете установить для переменной значение true, если строка соответствует 1-му разделителю, и значение false, если оно соответствует второму и печатать только тогда, когда оно истинно:
awk '/\*{4,}/{a=1; next}/<np>/{a=0}(a==1){print}' file
Приведенная выше команда установит a
в 1, если текущая строка соответствует 4 или более *
, а также перейдет к следующему
строка. Это означает, что строка ***
никогда не будет напечатана.
Это был ответ на первоначальную, неправильно понятую версию вопроса. Я оставляю его здесь, так как он может быть полезен в немного другой ситуации.
Прежде всего, вам не нужна FS
(разделитель полей), вы хотите RS
(разделитель записей). Затем, чтобы передать литерал *
, вам нужно дважды экранировать его. Один раз для экранирования *
и один раз для экранирования обратной косой черты (в противном случае awk попытается сопоставить его так же, как \ r
или \ t
). Затем вы печатаете вторую «строку»:
$ awk -vRS='\\*\\*\\*' 'NR==2' file
thingsIwantToRead1
thingsIwantToRead2
thingsIwantToRead3
Чтобы избежать пустых строк вокруг вывода, используйте:
$ awk -vRS='\n\\*\\*\\*\n' 'NR==2' file
thingsIwantToRead1
thingsIwantToRead2
thingsIwantToRead3
Обратите внимание, что здесь предполагается ***
после каждого абзаца. , а не только после первого, как вы показываете.
В дополнение к ответу @ Terdon с AWK (и SED) вы можете использовать диапазон диапазона:
awk '/sep1/,/sep2/{print}' file
или
sed -n '/sep1/,/sep2/p' file
будет напечатать все (в том числе) SEP1
и SEP2
Отказ То есть:
~$ awk '/sep1/,/sep2/{print}' file
sep1
thingsIwantToRead1
thingsIwantToRead2
thingsIwantToRead3
sep2
В вашем случае:
~$ awk '/\*\*\*/,/^$/{print}' file
***
thingsIwantToRead1
thingsIwantToRead2
thingsIwantToRead3
Тогда вы можете удалить первую и последнюю строку.
Например, с:
~$ sed -n '/\*\*\*/,/^$/p' file | sed '1d;$d'
thingsIwantToRead1
thingsIwantToRead2
thingsIwantToRead3
или
~$ awk '/\*\*\*/,/^$/{print}' file | awk 'NR>1&&!/^$/ {print}'
thingsIwantToRead1
thingsIwantToRead2
thingsIwantToRead3
, если ваш абзац не слишком длинный.
Используя Perl:
< inputfile perl -0777 -pe 's/.*[*]+\n(.*) <np>\n.*/$1/s' > outputfile
<входной файл
: перенаправляет содержимое входного файла inputfile
на perl
stdin
-0777
: заставляет Perl вывести строки-e
сразу по всему файлу, а не строку за строкой-p
: заставляет Perl вывести строки-e
: заставляет Perl читать строку программы из аргументов> outputfile
: перенаправляет содержимое perl
's stdout
в outputfile
Regex breakdown:
s
: утверждает, что выполняет подстановку/
: запускает шаблон поиска. *[*]+\n
: совпадает любое количество любого символа до конца строки, заканчивающейся одним или более *
символом, за которым сразу следует символ новой строки (.*)
: совпадает и группирует любое количество любого символа до любого символа, за которым сразу же следует \n
строка. *
: совпадает с любым количеством любого символа/
: останавливает шаблон поиска / начинает замену шаблона$1
: заменяет на захваченную группу/
: останавливает замену шаблона / начинает замену модификаторовs
: утверждает, что рассматривает входную строку как единую строку, заставляя .
также для сопоставления символов новой строкиВывод образца:
~/tmp$ cat inputfile
13.2000000000 , 3*0.00000000000 , 11.6500000000 , 3*0.00000000000 , 17.8800000000
Blablabla
SATELLITE EPHEMERIS
===================
Output frame: Mean of J2000
Epoch A E I RA AofP TA Flight Ang
*****************************************************************************************************************
2012/10/01 00:00:00.000 6998.239 0.001233 97.95558 77.41733 89.98551 290.75808 359.93398
2012/10/01 00:05:00.000 6993.163 0.001168 97.95869 77.41920 124.72698 274.57362 359.93327
2012/10/01 00:10:00.000 6987.347 0.001004 97.96219 77.42327 170.94020 246.92395 359.94706
2012/10/01 00:15:00.000 6983.173 0.000893 97.96468 77.42930 224.76158 211.67042 359.97311
<np>
----------------
Predicted Orbit:
----------------
Blablabla
~/tmp$ < inputfile perl -0777 -pe 's/.*[*]+\n(.*) <np>\n.*/$1/s'
2012/10/01 00:00:00.000 6998.239 0.001233 97.95558 77.41733 89.98551 290.75808 359.93398
2012/10/01 00:05:00.000 6993.163 0.001168 97.95869 77.41920 124.72698 274.57362 359.93327
2012/10/01 00:10:00.000 6987.347 0.001004 97.96219 77.42327 170.94020 246.92395 359.94706
2012/10/01 00:15:00.000 6983.173 0.000893 97.96468 77.42930 224.76158 211.67042 359.97311
~/tmp$
Using Perl:
< inputfile perl -0777 -pe 's/.*[*]{3}\n(.*\n)\n.*/$1/s' > outputfile
< inputfile
: перенаправляет содержимое входного файла
на perl
stdin
-0777
: заставляет Perl замять весь файл сразу, а не строку за строкой-p
: заставляет Perl выводить строки-e
: заставляет Perl читать строку программы из аргументов> выходного файла
: перенаправляет содержимое perl
's stdout
в outputfile
Regex breakdown:
s
: утверждает, что выполняет подстановку/
: запускает шаблон поиска. *[*]{3}\n
: совпадает любое количество любого символа до конца строки ***\n
string(.*\n)\n
: совпадает и группирует любое количество любого символа до символа новой строки, за которым сразу следует символ новой строки. *
: совпадает с любым количеством любого символа/
: останавливает шаблон поиска / запускает шаблон замены$1
: заменяет на захваченную группу/
: останавливает шаблон замены / запускает модификаторыs
: утверждает, что входная строка рассматривается как одна строка, заставляя .
также для согласования символов новой строки: выходной сигнал образца:
~/tmp$ cat inputfile
blablabla
blablabla
***
thingsIwantToRead1
thingsIwantToRead2
thingsIwantToRead3
blablabla
blablabla
~/tmp$ < inputfile perl -0777 -pe 's/.*[*]{3}\n(.*\n)\n.*/$1/s'
thingsIwantToRead1
thingsIwantToRead2
thingsIwantToRead3
~/tmp$
С sed
есть два пути. Вы можете выбрать включительно или исключительно. В вашем случае выбор включительно означает печать всех строк, начинающихся с совпадения по '^*\*\*'
до одной из ^ *
(что бы это ни было) или ^$
пустой строки.
Выборка включительно может быть задана с помощью любого из выражений диапазона, продемонстрированных в других ответах, и предполагает указание образца начать печатать здесь до образца до конца здесь.
Выбор эксклюзивный работает противоположным образом. Он определяет от остановить печать до здесь до начать печать после здесь. Для вашего примера данных - и позволяя остановить печать до здесь, который будет соответствовать любой из пустых строк или , что
вещь:
sed -e 'x;/^\( *<np>.*\)*$/,/^*\** *$/c\' -e '' <infile >outfile
x
sed
всегда на одну строку позади ввода - и первая строка всегда пустая. /^\( *.*\)*$/
. /^*\** *$/
*
звездочки и продолжается до конца строки с нулем или более вхождений *
звездочки и, возможно, закрывается любым количеством пробелов. c\' -e ''
c
переводит весь заблокированный выбор в одну пустую строку, сжимая все ненужные строки до строки EOF
. Таким образом, любое количество строк, встречающихся до ^*\** *$
и после первой следующей ^\( *
, всегда сжимается до единственной пустой строки, и только первый встречающийся параграф после совпадения для ^*\** *$
выводится в stdout. Печатается...
2012/10/01 00:00:00.000 6998.239 0.001233 97.95558 77.41733 89.98551 290.75808 359.93398 2012/10/01 00:05:00.000 6993.163 0.001168 97.95869 77.41920 124.72698 274.57362 359.93327 2012/10/01 00:10:00.000 6987.347 0.001004 97.96219 77.42327 170.94020 246.92395 359.94706 2012/10/01 00:15:00.000 6983.173 0.000893 97.96468 77.42930 224.76158 211.67042 359.97311
Это предполагает, что вы хотите обрабатывать любое количество вхождений шаблона параграфа во входных данных. Если вам нужен только первый, однако, при условии, что у вас есть GNU grep
и что infile
является обычным, lseekable файлом:
{ grep -xm1 '*\** *' >&2
sed -n '/^\( *<np>.*\)*$/q;p'
} <infile 2>/dev/null >outfile
... будет работать также.
И на самом деле, я полагаю, есть три способа. Третий может выглядеть так:
sed 'H;$!d;x;s/\(\n\*\** *\n\(\([0-9./: ]*\n\)*\)\)*./\2/g'
... который читает весь файл, а затем глобально заменяет каждый символ, который не попадает в спецификации совпадающих строк. Он печатает то же самое, что и раньше, но писать его очень тяжело, и он безопасен с точки зрения производительности, только если вы сбалансируете опции против любого символа.