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

Скажем, у меня есть следующее:

for i in $@; do echo ${i+1} done 

и я запускаю это на shell $ test.sh 3 5 8 4 , он выводит 1 1 1 1 почему бы не $ {i + 1} работать? Я пытаюсь получить доступ к следующему аргументу для списка аргументов командной строки.

4 Solutions collect form web for “как получить доступ к следующему аргументу параметров командной строки в bash?”

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

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

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

И читать:

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

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

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

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

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

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

Нет необходимости in "$@" (и привыкнуть к цитированию всех расширений).

 $ ./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 

косвенность

Как мы получаем доступ к аргументу в позиции $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 

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

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

Например:

 % check () { for i in "$@"; do echo $((i+1)); done ;} % check 2 4 5 6 3 5 6 7 

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

 #!/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 

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

 check () { for i in $(seq $#); do let j=i+1 echo "$i: i=${!i} i+1=${!j}" done } check abc 1: i=a i+1=b 2: i=b i+1=c 3: i=c i+1= 
  • вычесть строку из файла во все строки из другого файла
  • Как заставить backticks принимать переменные как переменные?
  • Ссылка на предыдущий вывод команды / содержимое экрана терминала в текущей командной строке
  • в чем разница между if и [[in bash?
  • Можно ли использовать скрипт bash для создания демона?
  • приостановка сценария bash до тех пор, пока не будут выполнены предыдущие команды
  • Как нечетко выраженный метасимвол может быть частью токена?
  • BASH getopts OPTARG undefined
  • Как выбрать все скрытые файлы в консоли?
  • Почему set-o errexit нарушает это выражение read / heredoc?
  • Параметры dd-стиля для сценария bash
  • Linux и Unix - лучшая ОС в мире.