Вы можете использовать Here String с синтаксисом <<<
:
ls | while IFS= read -r line
do
name=$(sed 's/\(.*\)/\1.jpg/' <<< $line) && mv "$line" "$name"
done
Имейте в виду, что не рекомендуется анализировать выходные данные ls
(или использовать нецитируемые переменные).
Существует также имя инструмента rename
(в случае, если целью является просто переименовать файл):
rename -n 's/$/.jpg/' *
Снимите флаг -n
, чтобы перейти от предварительного просмотра к фактическому переименованию.
Это возможно с eval :
$ declare -a array=( 1 2 3 4 )
$ echo "${array[@]}"
1 2 3 4
$ p=ay
$ tmp=arr$p
$ echo "$tmp"
array
$ echo "\${${tmp}[@]}"
${array[@]}
$ echo "newarray=(\"\${${tmp}[@]}\")"
newarray=("${array[@]}")
$ eval "newarray=(\"\${${tmp}[@]}\")"
$ echo "${newarray[@]}"
1 2 3 4
$
Команды, начинающиеся с echo, служат для иллюстрации, eval опасен.
Обратите внимание, что приведенное выше не сохраняет индексы массивов для разреженных массивов.
Косвенное расширение имеет некоторые исключения, и использование! в массивах - одно из исключений.
Из man bash:
Если первым символом параметра является восклицательный знак (!), Вводится уровень косвенного обращения к переменной . Bash использует значение переменной, образованной из оставшейся части параметра, в качестве имени переменной ; затем эта переменная расширяется, и это значение используется в остальной части замены, а не в значении самого параметра. Это называется косвенным раскрытием.
Исключением являются расширения $ {! Prefix *} и $ {! Name [@]} , описанные ниже. $ {! Prefix *} Префикс соответствия имен. Заменяется на имена переменных , имена которых начинаются с префикса, разделенного первым символом специальной переменной IFS.
Как описано в BASH FAQ06 , одно временное решение выглядит следующим образом:
arrA=("AA" "2" "4")
echo -e "array arrA contains: \c" && declare -p arrA
ref=arrA;
tmp=${ref}[@] #this can be adjusted to [1] , [2] etc to refer to particular array items
echo "Indirect Expansion Printing: ${!tmp}"
#Output
array arrA contains: declare -a arrA='([0]="AA" [1]="2" [2]="4")'
Indirect Expansion Printing: AA 2 4
bash
4.3 добавил поддержку ksh93
-подобных namerefs.
Поэтому в bash-4.3 и выше вы можете сделать:
a0[5]=whatever
x=0
typeset -n var="a$x"
printf '%s\n' "${var[5]}"
Но обратите внимание, что это ссылка (указатель, а не копия) на переменную name, а не сама переменная (разница имеет значение, когда у вас есть несколько переменных с одним и тем же именем в разных контекстах, как для локальных переменных в функциях).
bash
скопировал ksh
массивы с их неудобным дизайном. Сделать копию массива в bash
сложно, вы можете использовать вспомогательную функцию типа:
copy_array() { # Args: <src_array_name> <dst_array_name>
eval '
local i
'"$2"'=()
for i in "${!'"$1"'[@]}"; do
'"$2"'[$i]=${'"$1"'[$i]}
done'
}
Для использования, например, как:
$ a0[5]=123
$ x=0
$ copy_array "a$x" var
$ typeset -p var
declare -a var=([5]="123")
ksh
(и bash
, который копирует ksh
) - единственная оболочка, где массивы являются разреженными (или являются ассоциативными массивами, ключи которых ограничены целыми положительными числами) (также единственные массивы с индексами, начинающимися с 0, а не с 1, или где $array
неинтуитивно расширяется не до элементов, а до элемента с индексом 0). С другими оболочками все гораздо проще.
rc
: array_copy = $array
fish
: set array_copy = $array
csh
: set array_copy = ($array:q)
zsh
или yash
: array_copy=("${array[@]}"}
Для косвенного копирования (где $var
содержит имя исходного массива):
rc
: eval array_copy = '$'$var
fish
: eval set array_copy \$$var
csh
: eval "set array_copy = (\$$${var}:q)"
zsh
: array_copy=("${(@P)var}")
yash
(or zsh
): eval 'array_copy=("${'"$var"'[@]}")'