У меня есть переменная, в которой хранится строка, и мне нужно проверить, есть ли в ней строки:
var=`ls "$sdir" | grep "$input"`
псевдокод:
while [ ! $var's number of lines -eq 1 ]
do something
Это моя идея, как это проверить. echo $var | wc -l
не работает - всегда говорит 1
, хотя и работает 3
.
echo -e
тоже не работает.
if [ -z "$var" ]; then printf '%s\n' '0'; else printf '%s\n' "${var%$'\n'}" | wc -l; fi
. Попробуйте использоватьvar=
(без строк)var='foo'
иvar=$'foo\n'
(обе строки в смысле * nix).LINE_COUNT=$(wc -l <<< "${var}")
echo -n
просто уменьшит счетчик на единицу. @lucifurious по-echo $(wc -l <<< "${NONEXISTENTVAR}")
прежнему дает 1, а не 0Принятый ответ и другие опубликованные здесь ответы не работают в случае пустой переменной (неопределенной или пустой строки).
Это работает:
echo -n "$VARIABLE" | grep -c '^'
Например:
ZERO= ONE="just one line" TWO="first > second" echo -n "$ZERO" | grep -c '^' 0 echo -n "$ONE" | grep -c '^' 1 echo -n "$TWO" | grep -c '^' 2
источник
WHITESPACE_ONE=' '
в моей оболочке (bash) все еще работает, правильно сообщая одну строку.printf
вместоecho -n
. Я добавил это как альтернативный ответ, чтобы включить результаты тестов. Смотри ниже.Другой способ использования здесь строк в bash:
wc -l <<< "$var"
Как упоминалось в этом комментарии , пустой
$var
результат приведет к 1 строке вместо 0 строк, потому что здесь строки добавляют символ новой строки в этом случае ( объяснение ).источник
wc -l <<<"$(echo "$var")"
(да, каждый символ был необходим)$var
?var
содержит одну строку : Вы не интерпретируют\n
ни с чем. Поместите несколько строк в ваш,var
и он будет работать, например, сvar="foo<ENTER>bar<ENTER>baz"<ENTER>
.xxd <<< ''
создайте этот шестнадцатеричный дамп00000000: 0a
. Следовательно,<<<
(Here Strings) добавляет символ новой строки к любому содержимому.Вы можете заменить «wc -l» на «wc -w», чтобы лучше подсчитывать количество слов, а не строк. Это не будет считать новые строки и может использоваться для проверки того, пусты ли ваши исходные результаты, прежде чем продолжить.
источник
wc -l
solutions выводит 1, даже если входная переменная пуста, поэтомуwc -w
будет лучше использовать.Никто не упомянул о расширении параметров, поэтому вот несколько способов использования чистого bash.
Способ 1
Удалите символы, не являющиеся символами новой строки, затем получите длину строки +1. Цитаты важны .
var="${var//[!$'\n']/}" echo $((${#var} + 1))
Способ 2
Преобразуйте в массив, затем получите длину массива. Чтобы это сработало, не используйте кавычки .
set -f # disable glob (wildcard) expansion IFS=$'\n' # let's make sure we split on newline chars var=(${var}) echo ${#var[@]}
источник
IFS
. Поэтому установите,IFS=$'\n'
чтобы переменная была разделена на новые строки при расширении ее в массив:IFS=$'\n'; var=(${var})
set -f
необходим, чтобы избежать нежелательного расширения глобуса. Попробуйте использовать метод 2 наvar=$'*\n.*'
.wc -l
Более простая версия ответа @Julian, которая работает для всех строк, с завершающим \ n или без него (он считает файл, содержащий только один завершающий \ n, пустым):
printf "%s" "$a" | grep -c "^"
Вывод:
# a= # printf "%s" "$a" | grep -c "^" 0 # a="" # printf "%s" "$a" | grep -c "^" 0 # a="$(printf "")" # printf "%s" "$a" | grep -c "^" 0 # a="$(printf "\n")" # printf "%s" "$a" | grep -c "^" 0 # a="$(printf " \n")" # printf "%s" "$a" | grep -c "^" 1 # a="$(printf " ")" # printf "%s" "$a" | grep -c "^" 1 # a="aaa" # printf "%s" "$a" | grep -c "^" 1 # a="$(printf "%s" "aaa")" # printf "%s" "$a" | grep -c "^" 1 # a="$(printf "%s\n" "aaa")" # printf "%s" "$a" | grep -c "^" 1 # a="$(printf "%s\n%s" "aaa" "bbb")" # printf "%s" "$a" | grep -c "^" 2 # a="$(printf "%s\n%s\n" "aaa" "bbb")" # printf "%s" "$a" | grep -c "^" 2
источник
echo
(например,echo -n
) нестандартна и может давать разные результаты в разных реализациях. Аprintf
по умолчанию делает то, что мы хотим. В качестве бонуса использование usingprintf
сохраняет процесс, поскольку это встроенная оболочка. (Предложение:printf "$a" | wc -l
более лаконично и исключает ненужное использованиеgrep
)printf .... | wc -l
будет удалена только одна дополнительная строка (новая строка), так что в случае пустой строки результат будет 0 . Верный. Но если мы передадим 2 строки, результатом будет 1, где та же переменная, переданная вprintf ... | grep "^"
объект, вернет правильно 2. Кроме того, использование напрямуюprintf "$a"
очень опасно, потому что это может привести к тихим ошибкам, если строка случайно содержит такие символы, как%s
,%d
и так on ... То же самое, если строка начинается с тире. Вместо этого параметр 2 вprintf
автоматически экранируетсяСамые популярные ответы не пройдут, если grep не вернул никаких результатов.
Это неправильный способ сделать это :
wiggums=$(grep -iF "Wiggum" characters.txt); num_wiggums=$(echo "$wiggums" | wc -l); echo "There are ${num_wiggums} here!";
Там нам скажут, что в списке есть
1
Виггам , даже если его нет.Вместо этого вам нужно сделать еще одну дополнительную проверку, чтобы убедиться, что переменная пуста (например
-z
, «равна нулю»). Если grep ничего не вернул, переменная будет пустой.matches=$(grep -iF "VanHouten" characters.txt); if [ -z "$matches" ]; then num_matches=0; else num_matches=$(echo "$matches" | wc -l); fi echo "There are ${num_matches} VanHoutens on the list";
источник
Другой метод подсчета количества строк в переменной - если вы проверили, что она успешно заполнена или она не пуста, для этого просто проверьте $? после изменения результата подоболочки var -:
readarray -t tab <<<"${var}" echo ${#tab[@]}
readarray | mapfile - это внутренняя команда bash, которая преобразует входной файл или, в данном случае, строку , в массив на основе новых строк.
Флаг -t предотвращает сохранение новых строк в конце ячеек массива, полезно для дальнейшего использования сохраненных значений
Преимущества этого метода:
источник
Чтобы избежать имени файла в команде "wc -l":
lines=$(< "$filename" wc -l) echo "$lines"
источник