netstat выполняет обратный поиск в DNS, чтобы отобразить имя хоста вместо IP-адреса. Вы можете отключить обратный поиск DNS с помощью опции -n
.
Попробуйте это:
$ sudo netstat -anp
"\n"
— это два символа обратной косой черты и строчная буква n.
Теперь в некоторых оболочках echo "\n"
будет печатать символ новой строки (два, на самом деле ), и во всех оболочках printf "\n"
. Но это потому, что echo
и printf
обращаются с обратной косой чертой особым образом. Это в отличие от, например. C, Perl и Python, где символы обратной косой черты -всегда обрабатываются особым образом в (двойных -кавычках )строк.
Во многих оболочках $'\n'
будет строкой, содержащей символ новой строки и ничего больше. (Но в чистом POSIX sh вам понадобится буквальный перевод строки в кавычках.)
Тем не менее, в Bash/Ksh/Zsh вы могли просто проверить строку на соответствие регулярному выражению, а не зацикливаться вручную:
re=$'^[# \n]*$'
if [[ $string =~ $re ]]; then
echo "string contains only #, space and newline"
fi
(for ((.. ))
и ${string:i:j}
также не являются стандартными функциями POSIX и не будут работать, например. Dash, который Ubuntu имеет как /bin/sh
.)
Вы действительно не должны использовать sh (любой вариант, от простого старого sh до bash или ksh или zsh )для выполнения каких-либо операций, кроме самых тривиальных строк или обработки текста. См. Почему использование цикла оболочки для обработки текста считается плохой практикой? по некоторым причинам.
Перебор каждого символа многострочной -строки — это то, что определенно не следует делать в одной оболочке. Это будет ужасно медленно, и вы столкнетесь со всевозможными проблемами с цитированием и концом -из -маркеров строк (, таких как \n
), и большинством версий sh (, кроме bash, ksh и zsh )даже не имеют встроенной -поддержки регулярных выражений -, что является, IMO, минимально необходимой функциональностью для обработки текста.
Вместо этого используйте awk
или perl
или какую-либо другую утилиту/язык обработки текста -.
Например, вы можете заменить весь цикл for на:
echo "$string" | perl -lne 'BEGIN {$c="Yes"; $ec=0};
if (!m/^[ #]+$/) { $c="No"; $ec=1; last };
END {print $c; exit $ec}'
или
echo "$string" | awk -v c="Yes" -v ec=0 \
'!/^[ #]*$/ { c="No"; ec=1; nextfile };
END { print c; exit ec}'
Для этого требуется GNU awk (или другой awk, поддерживающийnextfile
). В других версиях awk следующее будет работать -, но немного медленнее, потому что не выходит из цикла сразу при плохом совпадении:
echo "$string" | awk -v c="Yes" -v ec=0 \
'!/^[ #]*$/ { c="No"; ec=1 };
END { print c; exit ec}'
Как должно быть очевидно,это все один и тот же сценарий, просто переписанный немного по-разному для разных синтаксисов perl и awk.
Регулярное выражение, используемое как в perl, так и в awk выше, равно /^[ #]*$/
, инвертировано с помощью !
. Это соответствует любой строке, которая не содержит только пробелы или хэши.
Все три из них возвращают код выхода 0 при подтвержденном -хорошем вводе и 1 при плохом совпадении. Это можно проверить в sh с помощью переменной $?
:
if [ $? -eq 1 ] ; then
: # string has bad characters, do something!
fi
Вы также можете использовать простой скрипт GNU sed
:
echo "$string" | sed -n -e '/[^ #]/q1'
if [ $? -eq 0 ] ; then echo "Yes" else echo "No" ; fi
Код выхода для командыq
(quit )является расширением GNU для sed, поэтому требуется GNU sed.
Или, как указал @Isaac, вы можете использовать опцию grep
-q
(или --quiet
/ --silent
). Это подавляет нормальный вывод и возвращает только код выхода. Например:
echo "$string" | grep -q '[^ #]'
if [ $? -eq 0 ] ; then echo "Yes" else echo "No" ; fi
Как указывали другие, "\n"
- это не новая строка, а просто строка с \
и n
в ней.
Если вы хотите определить, содержит ли строка только пробелы, хэши и символы новой строки, используйте сопоставление с образцом, а не просмотр каждого отдельного символа.
Можно и так:
case $string in
(*[![:space:]#]*)
echo 'other characters in string'
;;
(*)
echo 'only space-like characters or hashes in string'
esac
или так (вbash
):
if [[ $string == *[![:space:]#]* ]]; then
echo 'other characters in string'
else
echo 'only space-like characters or hashes in string'
fi
Здесь [:space:]
я использовал класс символов POSIX, который будет соответствовать всем видам пробелов, -например, символам, включая пробел, вкладки (различных типов ), каретку -возврат и новая строка. Шаблон *[![:space:]#]*
будет соответствовать любой строке, содержащей символ, который является , а не символом, подобным пробелу -, или символом #
.
Если вы хотите ввести более строгие ограничения, например, запретив табуляцию или возврат каретки -, тогда используйте $'*[! \n#]*'
в качестве шаблона вbash
:
pattern=$'*[! \n#]*'
if [[ $string == $pattern ]]; then
echo 'other characters in string'
else
echo 'only spaces, hashes, or newlines in string'
fi
Или в стандартной sh
оболочке:
pattern='*[!
#]*'
case $string in
($pattern)
echo 'other characters in string'
;;
(*)
echo 'only spaces, hashes, or newlines in string'
esac