iptables -A INPUT -p tcp --dport 25 -m set --set blocking src -j DROP
iptables -A INPUT -p tcp --dport 143 -m set --set blocking src -j DROP
... или безотносительно портов Вы используете.
Проблема заключалась в том, что по умолчанию echo
добавляет новую строку при каждом вызове и sed
работал на этих новых линиях. Вы не могли этого увидеть, потому что, когда bash обрабатывает $ (...)
, эти новые строки преобразуются в пробелы. Итак, чтобы исправить проблему, внося минимальные изменения в ваш подход:
$ x=$(for i in a b c; do echo -n "${i}",; done| sed 's/,$//') ; echo $x
a,b,c
Параметр -n
указывает echo
не добавлять новые строки.
Если вам нужны пробелы между элементами, их легко добавить:
$ x=$(for i in a b c; do echo -n "${i}, " ; done| sed 's/, $//') ;echo $x
a, b, c
проверьте следующий скрипт
$ cat run.sh #!/bin/bash echo example 1 for i in a b c; do echo "${i},"; done echo example 2 for i in a b c; do echo "${i},"; done|sed '$s/,//' echo example 3 for i in a b c; do echo "${i}"; done|sed '$!s/$/,/' echo example 4 SEP=''; for i in a b c; do printf "${SEP}${i}"; SEP=',\n'; done; printf '\n' echo example 5 STR=''; SEP=''; for i in a b c; do STR="${STR}${SEP}${i}"; SEP=,; done; echo $STR echo example 6 echo 'a,b,c,'||sed 's/^\(.*\),\(^,\)*$/\1\2/' echo example 7 echo 'a,b,c,'|sed 's/.\w*$//'
Он дает следующий результат
$ . run.sh example 1 a, b, c, example 2 a, b, c example 3 a, b, c example 4 a, b, c example 5 a,b,c example 6 a,b,c example 7 a,b,c
пример 1: наш цикл for фактически производит строки . echo $ x
преобразует это в одну строку.
пример 2: вы можете указать sed обрабатывать только последнюю строку
пример 3: вы можете указать sed обрабатывать все, кроме последней строки
пример 4: вы можете запрограммировать свой цикл for, чтобы вы выполняли некоторые специальные обработка при первом запуске: не готовить ', \ n' к строке.Но во многих случаях вы не знаете, когда оно было выполнено в последний раз
пример 5: то же, что и пример 4, но вы не создаете строки, а просто строку
пример 6: скажите sed удалить последнее вхождение строки в строке
пример 7: скажите sed удалить последний непробельный символ строки
$ w=(a b c)
$ IFS=, eval 'echo "${w[*]}"'
a,b,c
Примечание, разве мы не изобретаем колесо здесь?
{ {1}} Для массива a = (1 2 3 4 5)
Если вы можете изменить массив:
for (( i=$((${#a[@]}-1)); i-->0; )); do a[i]+=","; done echo "${a[@]}" 1, 2, 3, 4, 5
$ (($ {# a [@ ]} - 1))
вычисляет предпоследний индекс массива, а a [i] + = ","
добавляет строку.
Если вы хотите сделать это в функции:
print_with_commas() { while [[ $# -gt 1 ]];do echo -n "$1, ";shift;done;echo "$1" } print_with_commas "${a[@]}" 1, 2, 3, 4, 5
Вывести каждый аргумент функции, кроме последнего, и повторить эхо с добавлением ","
без новой строки. Затем повторите последний аргумент и новую строку.
Один из вариантов - использовать bash
arr=(a b c)
x=$(IFS=,;printf "%s" "${arr[*]}")
echo "$x"
a,b,c
Альтернативно
arr=(a b c)
printf -v x "%s," "${arr[@]}"
x=${x%,}
echo "$x"
a,b,c
Во втором варианте вы можете установить разделитель на ,
(запятая, за которой следует пробел) вместо ,
только
printf -v x "%s, " "${arr[@]}"
x=${x%, }
echo "$x"
a, b, c
, другой полезный метод для этого - paste -s
:
$ arr=(a b c)
$ printf "%s\n" "${arr[@]}" | paste -sd,
a,b,c
(обратите внимание, что paste -sd,
здесь является очень общей операцией «превратить этот набор элементов, разделенных новой строкой, в список, разделенный запятыми»)
Зачем вообще нужно удалять последнюю запятую?
Вы все путаете, а затем пытаетесь навести порядок после этого, вместо того, чтобы правильно подумать о проблеме с самого начала.
Существует решение, когда вы смотрите на запятую как на расположенную не после каждого элемента, а перед каждым элементом.
for i in a b c; do
u="${u:+$u, }$i"
done
echo $u
См. Подстановка параметров bash .
Результат:
a, b, c