как получить доступ к следующему аргументу параметров командной строки в bash?

Вы можете попробовать awk :

$ awk -F . '$NF !~ /^0/' <file
129.130.100.100
3
10.02.2016, 07:42
4 ответа

Каждый символ в оболочке может иметь особое значение.

Код $ {i + 1} не означает «прибавить 1 к i».
Чтобы узнать, что это означает, выполните эту команду:

LESS=+/'\{parameter\:\+word\}' man bash

И прочтите:

$ { параметр : + слово }
Используйте Альтернативное значение. Если параметр равен нулю или не задан, ничего не заменяется, в противном случае подставляется расширение слова.

И немного выше:

Отсутствие двоеточия приводит к тестированию только для параметра, который не установлен.

Поскольку $ i имеет значение, установленное циклом для i в $ @, заменяется «Альтернативное значение» и печатается 1 .

Если вы хотите добавить 1 к значению аргументов, сделайте следующее:

for    i
do     echo "$((i+1))"
done

Нет необходимости в в «$ @» (и привыкайте цитировать все расширения).

$ ./test.sh 3 5 8 4
4
6
9
5

Следующий аргумент.

Но это тоже не «следующий аргумент». Основная проблема заключается в вашем цикле, вы используете значение аргументов в цикле, а не индекс аргументов. Вам нужно перебрать индекс i аргументов, а не значение i каждого аргумента. Что-то вроде:

for (( i=1; i<=$#; i++)); do
    echo "${i}"
done

Это напечатает индекс, как показано здесь:

$ ./test.sh 3 5 8 4
1
2
3
4

Indirection

Как нам получить доступ к аргументу в позиции $ i ?: С косвенным обращением:

for (( i=1; i<=$#; i++)); do
    echo "${!i}"
done

См. Простой ! добавил?

Теперь он работает так:

$  ./test.sh  3 5 8 4
3
5
8
4

Окончательное решение.

И чтобы вывести и текущий аргумент, и следующий, используйте это:

for (( i=1; i<=$#; i++)); do
    j=$((i+1))
    echo "${!i} ${!j}"
done

Нет, нет более простого способа, чем вычислить значение в переменной $ j .


$ ./test.sh 3 5 8 4
3 5
5 8
8 4
4 

Это также работает для текста:

$ ./test.sh sa jwe yqs ldfgt
sa jwe
jwe yqs
yqs ldfgt
ldfgt 
4
27.01.2020, 21:18

Сначала обратите внимание, что $ {i + 1} - это шаблон расширения параметра, что означает, что если параметр i не сброшен или равен нулю, он будет заменен раскрытием 1 , что, конечно же, приводит только к 1 . Следовательно, вы получаете на выходе все единицы.

Вам нужно использовать арифметический оператор, а не расширение параметров.

Например:

% check () { for i in "$@"; do echo $((i+1)); done ;} 

% check 2 4 5 6
3
5
6
7
0
27.01.2020, 21:18

Я использую сдвиг для той же цели. Вот небольшой пример, взятый из здесь :

#!/bin/bash

# This script can clean up files that were last accessed over 365 days ago.

USAGE="Usage: $0 dir1 dir2 dir3 ... dirN"

if [ "$#" == "0" ]; then
    echo "$USAGE"
    exit 1
fi

while (( "$#" )); do

if [[ $(ls "$1") == "" ]]; then 
    echo "Empty directory, nothing to be done."
  else 
    find "$1" -type f -a -atime +365 -exec rm -i {} \;
fi

shift
0
27.01.2020, 21:18

В вашем примере кода i - это значение, а не индекс.
Вам понадобится восклицательный знак для использования переменной значение как переменная.
Я не смог заставить (i + 1) работать без определения другой переменной. Может, кто-нибудь подскажет, как это оптимизировать.

check () {
  for i in $(seq $#); do
    let j=i+1
    echo "$i: i=${!i} i+1=${!j}"
  done
}

check a b c

1: i=a i+1=b
2: i=b i+1=c
3: i=c i+1=
0
27.01.2020, 21:18

Теги

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