2016-12-21 2 views
1

Это, наверное, глупый вопрос, больше из любопытства. У меня есть массив в Баш:Как назначить диапазон с использованием длины массива?

array=(name1.ext name2.ext name3.ext)

Я хочу, чтобы сдирать расширение от каждого элемента. Я пытался сделать это с помощью цикла по каждому элементу, но я с настройкой диапазона петли проблемы (см):

for i in 'echo {0..'expr ${#array[@]} - 1'}'; do newarray[$i]+=$(echo "${array[$i]:0:5}"); done

Пожалуйста, обратите внимание, "=„назад-тик“в code- потому что я не был уверен, как избежать этого.

Я не могу использовать только заданный диапазон (например, seq 0 3), потому что он изменяется в зависимости от папки, поэтому я хотел иметь возможность использовать длину массива минус 1. Я смог обойти это с помощью:

for ((i=0; i<${#array[@]}; i++)); do newarray[$i]+=$(echo "${array[$i]:0:5}"); done

Но я думал, что должен быть какой-то способ сделать это с «длиной массива минус 1» выше способом, и спрашивает, как я думал об этом неправильно. Любые указатели оцениваются.

Спасибо! Dan

+1

процитировать 'обратно tick' внутри«дублирующей галочкой»блок, просто избежать обратно клеща, например,' '\ убежал обратно tick'. – Jdamian

+0

Я не могу понять, что вы хотите получить, и в чем проблема. – Jdamian

+0

Я понял, что вы хотите запустить массив с помощью последовательности индексов, а не увеличивать счетчик, но я не понимаю проблему. – Jdamian

ответ

1

Вы можете применять различные операторы расширения параметров к каждому элементу массива напрямую, без необходимости явного цикла.

$ array=(name1.ext name2.ext name3.ext) 
$ printf '%s\n' "${array[@]%.ext}" 
name1 
name2 
name3 
$ newarray=("${array[@]%.ext}") 

В общем, тем не менее, почти нет необходимости генерировать номера диапазонов для перебора. Просто используйте C-стиль for цикла:

for ((i=0; i< ${#array[@]}; i++)); do 
    newarray[$i]="${array[i]%.ext}" 
done 
+0

Большое спасибо @chepner за хорошее объяснение. У меня есть один несколько не связанный с этим вопрос. Я назначаю свой массив подстановочным знаком, например. 'array = (name * .ext)', а затем используйте ваше предложение, чтобы снять расширение. Однако, когда я вызываю эту переменную позже в скрипте: 'for i в $ {newarray [@]}; do fslcommand "$ i" входной выход; done', он не работает, потому что шаблон не расширяется. Должен ли я не использовать подстановочный знак для назначения массива? –

+1

Подстановочный знак расширяется при назначении 'array'. Однако, если ничего * не соответствует * шаблону, массив содержит литеральный шаблон в качестве единственного элемента, если вы раньше не устанавливали 'shopt -s nullglob'. Не забудьте указать расширение в случае, если любое из полученных имен файлов содержит пробелы или метасимволы шаблонов: 'for i in '$ {newarray [@]}"; do' – chepner

+0

Хорошо, теперь я чувствую себя еще глупее. Я не правильно настраивал полный путь, поэтому, конечно, это не соответствовало чему-либо. Спасибо, что заставило меня понять мою ошибку! –

0

Вы можете использовать seq команды

for i in `seq 0 $((${#array[@]} - 1))` 
do 
     ··· 
done 

или расширение Баша распорки (но в этом случае вам нужно eval):

for i in `eval echo {0..$((${#array[@]} - 1))}` 
do 
     ··· 
done 

Но есть еще один лучше (он работает даже в разреженных массивах): давайте сделаем bash, дадим нам индексы массива:

for i in ${!array[@]} 
do 
     ··· 
done 
2

С Bash, вы могли бы просто перебирает ваши элементы массива с ${files[@]}:

#!/bin/bash 
files=(name1.ext name2.ext name3.ext) 

for f in ${files[@]}; do 
    echo "${f%.*}" 
done 

подстрока Также удалением ${f%.*} является лучшим выбором, если у вас есть расширения различной длины.

+0

в вашем решении массив имеет только один элемент, поэтому нет' $ {files [@]} 'необходимо. – Jdamian

+0

Ты прав @Jdamian. Я редактировал. – SLePort

Смежные вопросы