Вы можете немного уменьшить количество операций и пропустить вызовseq
:
for (( i = 1; i < ${#myarr[@]} - 1; ++i )); do
newarr+=( "${myarr[i]}" "${myarr[i]}" )
done
newarr=( "${myarr[0]}" "${newarr[@]}" "${myarr[-1]}" )
Это предполагает, что newarr
изначально пуст. Сначала выполните unset newarry
, если это не так.
Как функция (изменяет передаваемый массив):
dup_interal_items () {
typeset -n arr=$1
local tmparr
for (( i = 1; i < ${#arr[@]} - 1; ++i )); do
tmparr+=( "${arr[i]}" "${arr[i]}" )
done
arr=( "${arr[0]}" "${tmparr[@]}" "${arr[-1]}" )
}
Имя массива передается в функцию, а имя -ссылочной переменной arr
используется для доступа к элементам массива. В конце исходный массив обновляется, чтобы содержать результат.
Я сделал это таким образом, а не возвращал массив, поскольку вы можете вернуть только статус выхода из функции. Другой подход состоял бы в том, чтобы передать имена входного массива и выходного массива и использовать в функции две ссылочные переменные имени -.
Или вы могли бы, возможно, echo
или printf
значения в функции (, и в этом случае вам вообще не нужно создавать новый массив ), а затем анализировать эти данные в основном коде..Затем функция должна быть вызвана внутри подстановки команд.
Обратите внимание, что вы не можете вызвать эту функцию с массивом с именем arr
из-за особых правил области видимости имени, используемых bash
. Вы можете переименовать переменную arr
в функции, если это проблема.
Тестирование:
$ myarr=( 1 2 3 "here we go" )
$ dup_interal_items myarr
$ printf 'Element: %s\n' "${myarr[@]}"
Element: 1
Element: 2
Element: 2
Element: 3
Element: 3
Element: here we go
Чтобы дублировать все строки файла, кроме первой и последней строки:
sed -e '1b' -e '$b' -e 'p' <file
Сценарий sed
переходит в конец (, где есть неявный оператор печати ), если он находится в первой или последней строке, но печатает все остальные строки (поэтому все остальные строки печатаются явно этим последним p
и неявно напечатанным ).
Или, согласно дону _Криссти,
sed 'p;1d;$d' <file
который явно печатает каждую строку, затем завершает цикл для первой и последней строки, но неявно печатает все остальные строки (во второй раз ).
Эквивалентную awk
программу, которая не хранит в памяти более одной строки, было бы -непросто написать.
GNU screen
принимает ряд опций, а затем необязательную команду для запуска в сеансе экрана. Если команда не указана, сеанс screen
будет содержать сеанс интерактивной оболочки. Сеанс screen
завершается, когда завершается команда, которую он запускает, независимо от того, является ли это командой, заданной в командной строке screen
, или оболочкой, которую он запускает иным образом.
У вас две проблемы:
screen
. Чтобы решить первую из них, сделайте команду, которая начинает screen
как
sh -c 'hostname; echo yes; echo no'
Это единственная команда, которая запускает скрипт в -строке sh -c
. Этот скрипт запускает ваши команды. Вы можете использовать bash -c
вместо sh -c
, если скрипт, который вы запускаете, требует bash
(, а ваш пример не требует ).
Чтобы решить вторую проблему, рассмотрите запуск интерактивной оболочки в качестве последнего шага в списке команд, которые выполняет скрипт sh -c
:
sh -c 'hostname; echo yes; echo no; exec bash -i'
exec bash -i
запускает интерактивный bash
сеанс оболочки (exec
заставляет его заменить sh -c
оболочку ).
Запуск в screen
сеансе:
screen sh -c 'hostname; echo yes; echo no; exec bash -i'
GNU screen
прекратит работу после завершения bash -i
сеанса оболочки.