Переменная номер аргумента не учитывает введенные параметры [дубликат]

Необходимо использовать буфер строк.

Попробуйте следующее:

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 -я строка перед шаблоном.

3
23.11.2018, 09:53
3 ответа

Что вы делаете не так

Вы путаете входные аргументы (скрипта при запуске )и пользовательский ввод, используя чтение (во время выполнения ).

$#сообщает количество аргументов при запуске. например. для ./«script_name» 1 2 3при использовании в скрипте будет возвращено 3.

4
27.01.2020, 21:09

Чтобы проверить, получили ли вы значения для всех переменных и выйти в противном случае, используйте тест -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
7
27.01.2020, 21:09

Вы можете использовать команду 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
0
27.01.2020, 21:09

Теги

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