Удалите последнюю запятую из удара для сгенерированной строки цикла

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

... или безотносительно портов Вы используете.

6
29.04.2014, 23:41
7 ответов

Проблема заключалась в том, что по умолчанию 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
6
27.01.2020, 20:20

проверьте следующий скрипт

$ 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 удалить последний непробельный символ строки

0
27.01.2020, 20:20
$ w=(a b c)

$ IFS=, eval 'echo "${w[*]}"'
a,b,c

Примечание, разве мы не изобретаем колесо здесь?

{ {1}}
1
27.01.2020, 20:20

Для массива 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

Вывести каждый аргумент функции, кроме последнего, и повторить эхо с добавлением "," без новой строки. Затем повторите последний аргумент и новую строку.

0
27.01.2020, 20:20

Один из вариантов - использовать 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
9
27.01.2020, 20:20

, другой полезный метод для этого - paste -s :

$ arr=(a b c)
$ printf "%s\n" "${arr[@]}" | paste -sd,
a,b,c

(обратите внимание, что paste -sd, здесь является очень общей операцией «превратить этот набор элементов, разделенных новой строкой, в список, разделенный запятыми»)

{{1} }
4
27.01.2020, 20:20

Зачем вообще нужно удалять последнюю запятую?

Вы все путаете, а затем пытаетесь навести порядок после этого, вместо того, чтобы правильно подумать о проблеме с самого начала.

Существует решение, когда вы смотрите на запятую как на расположенную не после каждого элемента, а перед каждым элементом.

for i in a b c; do
  u="${u:+$u, }$i"
done
echo $u

См. Подстановка параметров bash .

Результат:

a, b, c
1
27.01.2020, 20:20

Теги

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