Повторяющиеся элементы массива, кроме первого и последнего элементов.

Рассмотрим также этот awkодин -вкладыш:

nmap -Pn -oG -p22,80,443,445 - 100.100.100.100 | awk '/open/{ s = ""; for (i = 5; i <= NF-4; i++) s = s substr($i,1,length($i)-4) "\n"; print $2 " " $3 "\n" s}'

Он напечатает вам все хосты со всеми указанными открытыми портами:

 100.100.100.100 (some-domain.com)
 22/open/tcp//ssh
 80/open/tcp//http
 443/open/tcp//microsoft-ds
 445/open/tcp//https-alt
0
17.11.2018, 20:46
3 ответа

Попробуйте также -функция не требуется-

$ ARR=(1 2 3 4 5)
$ IFS=$'\n\t '
$ readarray NEWARR < <(echo "${ARR[*]}" | sed '1!p; $d')
$ echo ${NEWARR[@]}
1 2 2 3 3 4 4 5

или даже

NEWARR=($(printf "%s\n" ${ARR[@]} | sed '1!p; $d'))
1
28.01.2020, 02:18

Решение, допускающее перевод строки:

#!/bin/bash
arr=( 1 2 "3 3" $'41\n42' 5 )

readarray -t -d $'\0' newarray < <(printf '%s\0' "${arr[@]}" | sed -z '1!p; $d')

printf '<%s>\n' "${newarr[@]}"

Работает как:

$./script
<1>
<2>
<2>
<3 3>
<3 3>
<41
42>
<41
42>
<5>
1
28.01.2020, 02:18

Вы можете немного уменьшить количество операций и пропустить вызов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программу, которая не хранит в памяти более одной строки, было бы -непросто написать.

2
28.01.2020, 02:18

Теги

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