Необходимо использовать буфер строк.
Попробуйте следующее:
awk -v N=4 -v pattern="example.*pattern" '{i=(1+(i%N));if (buffer[i]&& $0 ~ pattern) print buffer[i]; buffer[i]=$0;}' file
Установите значение N
на N-ю строку перед шаблоном для печати.
Установить значение шаблона
для регулярного выражения для поиска.
buffer
- это массив из N
элементов. Он используется для хранения строк. Каждый раз при нахождении шаблона печатается N
-я строка перед шаблоном.
Вы путаете входные аргументы (скрипта при запуске )и пользовательский ввод, используя чтение (во время выполнения ).
$#
сообщает количество аргументов при запуске. например. для ./«script_name» 1 2 3
при использовании в скрипте будет возвращено 3.
Чтобы проверить, получили ли вы значения для всех переменных и выйти в противном случае, используйте тест -z
для проверки пустых строк:
if [ -z "$one" ] || [ -z "$two" ] || [ -z "$three" ]; then
echo 'Did not get three values' >&2
exit 1
fi
Значение $#
— это количество позиционных параметров , обычно аргументов командной строки (или значений, установленных встроенной set
). Они доступны в $1
, $2
, $3
и т. д. (или вместе в массиве"$@"
)и не связаны со значениями, считываемыми встроенной командой read
.
Чтобы сценарий принимал входные данные в качестве аргументов командной строки, а не читал их в интерактивном режиме (, что может быть предпочтительнее, если пользователь должен указать один или несколько путей, поскольку он может воспользоваться преимуществами автодополнения с помощью табуляции -, и это также упрощает использование сценария из другого сценария и не требует подключения терминала ), используйте
if [ "$#" -ne 3 ]; then
echo 'Did not get three command line arguments' >&2
exit 1
fi
one=$1
two=$2
three=$3
В этом случае сценарий будет запускаться как
./script.sh a.plain /path/to/inputfile /path/to/outputfile
Если обработка ввода может происходить из стандартного ввода и вывод может быть отправлен на стандартный вывод (т.е. если вам на самом деле не нужны явные пути к входному файлу и выходу файл внутри скрипта ), тогда скрипт должен принимать только первый параметр(a.plain
или b.complex
).
./script.sh a.plain </path/to/inputfile >/path/to/outputfile
Затем сценарий будет использовать стандартный поток ввода и стандартный поток вывода для ввода и вывода (и, следовательно, должен будет только проверить одиночный аргумент командной строки ).
Это позволило бы запустить сценарий с данными, переданными из другой программы,а также позволит проводить дальнейшую пост-обработку -:
gzip -dc <file-in.gz |./script.sh a.plain | sort | gzip -c >file-out.gz
Вы можете использовать команду set
для повторной -установки позиционных аргументов, перезаписывая предыдущие значения. Переменная IFS
указывает список символов, которые будут использоваться в качестве разделителя, поэтому вы также можете использовать ее для анализа CSV. Обратите внимание, что set
является встроенным, поэтому обычный синтаксис для переопределения переменных для отдельных команд не работает, поскольку переменные, указанные перед командой, являются сокращением для команды env
, которая устанавливает среду для подпроцесса.
$#
— это количество позиционных аргументов, существующих на данный момент.
$ read foo
a b c d e
$ echo $foo
a b c d e
$ set -- $foo
$ echo $#
5
$ IFS=: set -- $foo # doesn't work
$ echo $#
5 # still got 5
$ IFS=:
$ set -- $foo
$ echo $#
1