Если я не очень хорошо знаю набор (или его дополнение) , я обычно не верю отрицанию - особенно диапазонов. Я ничего не знаю ни о большинстве этих символов в вашей уродливой строке, ни о том, откуда они взялись, и о том, заботит ли мой компьютер. Я знаю несколько других, и я знаю, как удалить все, кроме - при условии, что все уродливые символы являются, по крайней мере, действительными символами.
alnum=0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
sed -e's|.|&\n|g' -e'# this opens up the string' \
-e"s|\([-$alnum*_+ßäüö ()%&@=.$€]\)\{0,1\}.\{0,1\}\n|\1_|g" \
<<""
testflŒÆ˘ˆı››◊‹ıÓÌˇˆÁÓˆfl̈™ˇÏˆıÍÓÌıÓWÌtest
testWtest
^ это верно, верно?
Таким образом, он разбивает строку на \ n
строку для каждого символа, а затем просматривает строку по символу слева направо. При этом он будет выполнять одно из двух действий для каждого: либо он заменит один из ваших символов из белого списка на 0 или 1 вхождение самого себя, либо он удалит 0 или 1 вхождение какого-либо другого символа. В обоих случаях он также удаляет завершающий разделитель новой строки.
Думаю, легче увидеть, что он делает с _
подчеркиванием - (вероятно, поэтому вы их и включили) :
sed -e's|.|&\n|g' -e'# this opens up the string' \
-e"s|\([-$alnum*_+ßäüö ()%&@=.$€]\)\{0,1\}.\{0,1\}\n|\1_|g" \
<<""
testflŒÆ˘ˆı››◊‹ıÓÌˇˆÁÓˆfl̈™ˇÏˆıÍÓÌıÓWÌtest
_ _ _ _t_e_s_t________________________________W__t_e_s_t_
Это то, что sed
будет заменять строку с возможно нулевой длиной длиной. Удаление - это нормально, но sed
может принять это или оставить, и будет . О, пробелы, да, ну, я просто скопировал и вставил в терминал, поэтому четыре ведущих символа (для отступа блока кода Markdown) были пробелами.
Одна из причин, по которой я использую строки \ n
ewlines, связана с тем, что происходит с недопустимой последовательностью байтов в пространстве шаблонов. Если он не соответствует действительному символу, тогда .
не соответствует, и /^.*$/
завершится ошибкой. С новыми строками, если какие-либо символы, следующие за ошибочной последовательностью байтов, смогли соответствовать .
, тогда:
sed '/^.*$/!{/\n/D;}'
... будет работать и без него (но не с GNU sed
- думаю, мне следовало сначала проверить. Я использовал AST sed
ранее - что не беспокоит) . С GNU sed
z
будет z
ap для всего пространства шаблонов.
Переменная var
в вашем коде используется до того, как цикл начнет создавать выходной файл.
Если вы хотите вывести результат команды ssh
в файл, имя которого вы составляете из $var
, сделайте следующее:
#!/bin/bash
while read -r server; do
if [ "$server" = "198.162.1.3" ]; then
var='apple'
else
var='unknown'
fi
ssh -n "test@$server" 'uname -n' >"/tempout/uname_$var.txt"
done <servers
Здесь я также изменил цикл, чтобы он считывал входной файл построчно (, игнорируя начальные и конечные пробелы в каждой строке ), и я заставил var
получить значение unknown
если оператор if
не принимает "истинную" ветвь.
Кроме того, вам нужно -n
для ssh
. В противном случае ssh
использовал бы все доступные входные данные (, перенаправленные сюда из файла servers
).
Другое изменение, которое можно было бы внести, заключается в использовании оператора case... esac
вместо оператора if
, особенно если число проверяемых IP-адресов превышает пару:
#!/bin/bash
while read -r server; do
case $server in
198.162.1.3) var=apple ;;
198.162.1.5) var=cottage ;;
198.162.1.7) var=bumblebee ;;
*) var=unknown
esac
ssh -n "test@$server" 'uname -n' >"/tempout/uname_$var.txt"
done <servers