Рассмотрим также этот 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
Попробуйте также -функция не требуется-
$ 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'))
Решение, допускающее перевод строки:
#!/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>
Вы можете немного уменьшить количество операций и пропустить вызов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
программу, которая не хранит в памяти более одной строки, было бы -непросто написать.