$ awk 'NF > 10 { print NR }' data.in
Это выведет номера строк (на самом деле номера записей, но поскольку строка - это запись по умолчанию, разницы нет) каждой строки, содержащей более 10 полей. Поле - это строка, по умолчанию разделенная пробелами, если у вас другой разделитель, используйте -F
(-F ','
для запятых):
$ awk -F ',' 'NF > 10 { print NR }' data.in
Если вы хотите видеть строку, а не ее номер, это еще проще:
$ awk 'NF > 10' data.in
sort
может сортировать номера версий; пользуясь этим, вы можете написать что-то вроде этого:
if [ $(printf '%s\n2.15\n' $(ldd --version | sed -n '1s/.* //p') | sort -V | head -n 1) != 2.15 ]; then
# ...
fi
printf '%s\n2.15\n' $(ldd --version | sed -n '1s/.* //p')
печатает номер версии ldd
и 2. 15
на двух отдельных строках, sort -V
сортирует их в порядке возрастания и head -n 1
печатает первую строку; подстановка внешней команды заменяется выводом и вывод сравнивается с 2.15
; если вывод не равен 2.15
, выполняется тело if
.
Пример вывода на моей машине с ldd
2.21
:
% [ $(printf '%s\n2.15\n' $(ldd --version | sed -n '1s/.* //p') | sort -V | head -n 1) != 2.15 ] && printf 'Version %s is lower than 2.15\n' $(ldd --version | sed -n '1s/.* //p') || printf 'Version %s is equal or higher than 2.15\n' $(ldd --version | sed -n '1s/.* //p')
Version 2.21 is equal or higher than 2.15
Пример вывода на некоторых жестко закодированных значениях, просто чтобы показать, что метод справляется со сложностью сортировки версий:
% glibc_version=2.15
% [ $(printf '%s\n2.15\n' $glibc_version | sort -V | head -n 1) != 2.15 ] && printf 'Version %s is lower than 2.15\n' $glibc_version || printf 'Version %s is equal or higher than 2.15\n' $glibc_version
Version 2.15 is equal or higher than 2.15
% glibc_version=2.16
% [ $(printf '%s\n2.15\n' $glibc_version | sort -V | head -n 1) != 2.15 ] && printf 'Version %s is lower than 2.15\n' $glibc_version || printf 'Version %s is equal or higher than 2.15\n' $glibc_version
Version 2.16 is equal or higher than 2.15
% glibc_version=2.15.1
[ $(printf '%s\n2.15\n' $glibc_version | sort -V | head -n 1) != 2.15 ] && printf 'Version %s is lower than 2.15\n' $glibc_version || printf 'Version %s is equal or higher than 2.15\n' $glibc_version
Version 2.15.1 is equal or higher than 2.15
% glibc_version=2.14
% [ $(printf '%s\n2.15\n' $glibc_version | sort -V | head -n 1) != 2.15 ] && printf 'Version %s is lower than 2.15\n' $glibc_version || printf 'Version %s is equal or higher than 2.15\n' $glibc_version
Version 2.14 is lower than 2.15
ldd --version | sed 's/.* //;q' | awk -F. '{ if ($1 > 2 || ($1 == 2 && $2 >= 15)) { exit 0 } else {exit 1} }'
Объяснение:
Команда sed
берет первую строку вывода из ldd --version
, удаляет все до последнего пробела включительно, а затем завершает работу ( поэтому он печатает только номер).
Флаг -F
для awk
устанавливает .
как разделитель полей.
Если первое число (перед точкой) больше 2, или , если первое число равно 2, а второе - не менее 15, статус выхода awk
будет будь настоящим". В противном случае он будет ложным.
Вы можете использовать это в сценарии bash
следующим образом:
if ldd --version | sed 's/.* //;q' | awk -F. '{ if ($1 > 2 || ($1 == 2 && $2 >= 15)) { exit 0 } else {exit 1} }' ; then
echo "Version is 2.15 or later"
else
echo "Version is too old."
fi
Не преобразовывайте строку версии в целое число. Сравните струны.
Это немного излишне для вашего варианта использования, но вот функция оболочки, которая сравнивает типичные строки версий. Он следует подмножеству правил сравнения версий Debian :
Обратите внимание, что последняя точка: 1.01
считается равной 1.1
. Это цена, которую нужно заплатить за 1,1
и 1,9
, которые будут считаться меньшими, чем 1,10
.
Для этого кода требуется тире, bash, ksh или zsh. Чтобы использовать его с другими оболочками, такими как BusyBox sh, замените вызовы [" STRING1 " \> " STRING2 "]
на expr "a STRING1 "\>" a STRING2 "
.
version_ge () (
version1="$1" version2="$2"
while true; do
prefix1="${version1%%[0-9]*}" prefix2="${version2%%[0-9]*}"
if [ "$prefix1" \> "$prefix2" ]; then return 0; fi
if [ "$prefix2" \> "$prefix1" ]; then return 1; fi
version1="${version1#"$prefix1"}" version2="${version2#"$prefix2"}"
prefix1="${version1%%[!0-9]*}" prefix2="${version2%%[!0-9]*}"
version1="${version1#"$prefix1"}" version2="${version2#"$prefix2"}"
case "$prefix2" in
0*[!0]*) prefix2="${prefix2##"${prefix2%%[!0]*}"}";;
*[!0]*) :;;
*) return 0;;
esac
case "$prefix1" in
0*[!0]*) prefix1="${prefix1##"${prefix1%%[!0]*}"}";;
*[!0]*) :;;
*) return 1;;
esac
if [ "${#prefix1}" -gt "${#prefix2}" ]; then return 0; fi
if [ "${#prefix1}" -lt "${#prefix2}" ]; then return 1; fi
if [ "$prefix1" \> "$prefix2" ]; then return 0; fi
if [ "$prefix2" \> "$prefix1" ]; then return 1; fi
done
)