Невозможно перенаправить вывод Bash для переменного имени файла

Если я не очень хорошо знаю набор (или его дополнение) , я обычно не верю отрицанию - особенно диапазонов. Я ничего не знаю ни о большинстве этих символов в вашей уродливой строке, ни о том, откуда они взялись, и о том, заботит ли мой компьютер. Я знаю несколько других, и я знаю, как удалить все, кроме - при условии, что все уродливые символы являются, по крайней мере, действительными символами.

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 для всего пространства шаблонов.

3
07.09.2018, 12:44
1 ответ

Переменная 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
7
27.01.2020, 21:12

Теги

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