sed: извлечь номер версии из строки - PullRequest
3 голосов
/ 11 июля 2011

Ввод: adcheck (CentrifyDC 4.4.3-421)

Желаемый вывод: 4.4.3

То, что я думал, будет работать:

/usr/share/centrifydc/bin/adcheck --version | sed -n '/Centrify DC /,/-/p'

Но это ничего не выводит ??

Спасибо!

Ответы [ 6 ]

5 голосов
/ 11 июля 2011
sed 's/[[:alpha:]|(|[:space:]]//g' | awk -F- '{print $1}' <<< "(CentrifyDC 4.4.3-421)"

вывод: 4.4.3

Использование [:space:] для удаления лишних пробелов.

sed используется для удаления нежелательных символов, а awk -F- означает использование - в качестве разделителя полей

4 голосов
/ 11 июля 2011

Ваше решение не работает, потому что вы пытаетесь использовать адреса для выбора фрагмента строки, а адреса просто выбирают набор строк.Ваш код /Centrify DC /,/-/p будет печатать все строки между одной строкой, содержащей Centrify DC, и другой строкой, содержащей -.Он не работает только внутри одной строки, однако

Вам нужно удалить все из строки, кроме номера версии.Я бы порекомендовал вам сгруппировать номер версии и заменить на него все содержимое строки:

$ echo "adcheck (CentrifyDC 4.4.3-421)" | sed 's/^.*[^0-9]\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/'
4.4.3

Здесь мы помещаем номер версии в группу с \([0-9]*\.[0-9]*\.[0-9]*\) и заменяем всю строку группой(ссылается на \1).

Если ваш вход имеет более одной строки, может потребоваться некоторое туннелирование:

$ cat file
adcheck (CentrifyDC 4.4.3-421)
another line
still another line
$ sed 's/^.*[^0-9]\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/' file
4.4.3
another line
still another line

В этом случае передайте флаг -n в sedдля блокировки печати по умолчанию.Затем дайте адрес команде s/// (например, /adcheck (CentrifyDC /), чтобы гарантировать, что замена произойдет только в той строке, которая соответствует адресу.Наконец, добавьте флаг p к команде s/// - он напечатает строку сразу после замены:

$  sed -n '/adcheck (CentrifyDC /s/^.*[^0-9]\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/p' file
4.4.3
3 голосов
/ 26 октября 2013

одна строка скрипт

perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' YOURFILE.TXT

или чуть дольше, но обрабатывает несколько версий:

perl -nle 'print $v if ($v)=/([0-9]+([.][0-9]+)+)/' YOURFILE.TXT

примеры использования первой командной строки

$> V=$(perl -pe '($_)=/([0-9]+([.][0-9]+)+)/'<<<'adcheck (CentrifyDC 4.4.3-421)')
$> echo "$V"
4.4.3

$> V=$(perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' <<< 'dos2unix-8.2.3-beta.zip')
$> echo "$V"
8.2.3

$> echo 'A2 33. Z-0.1.2.3.4..5' | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/'
0.1.2.3.4

$> gcc --version | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/'
4.7.3

$> bash --version | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/'
4.2.45

$> meld --version | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/'
1.6.1

$> uname -a | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/'
3.8.0

$> perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' /etc/issue
13.04

Примечание: первая командная строка извлекает версию без окончательного возврата каретки (я имею в виду \n). Если это проблема, используйте вторую версию или оберните первую командную строку внутри echo:

$> echo $( perl --version | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' )
5.14.2

К сожалению, если есть несколько строк, содержащих номера версий, эти номера версий будут объединены:

$> echo $(gwenview --version | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' )

4.8.44.10.54.10.4

Чтобы извлечь одну версию на строку, необходимо изменить однострочный скрипт:

perl -pe 'if(($_)=/([0-9]+([.][0-9]+)+)/){$_.="\n"}'

пример:

$> gwenview --version | perl -pe 'if(($_)=/([0-9]+([.][0-9]+)+)/){$_.="\n"}' 
4.8.4
4.10.5
4.10.4

Чтобы извлечь только первый номер версии и добавление возврата каретки (я имею в виду новую строку \n), я советую:

perl -pe 'if(($v)=/([0-9]+([.][0-9]+)+)/){print"$v\n";exit}$_=""'

пример:

$> gwenview --version | perl -pe 'if(($v)=/([0-9]+([.][0-9]+)+)/){print"$v\n";exit}$_=""'
4.8.4

Для справки, моя попытка не так хороша. Кто знает, как получить то же поведение, что и мои perl сценарии, но с использованием sed?

sed 's/\([0-9][0-9]*[.][0-9][0-9.]*\)/\n\1/'

Если вы считаете, что можете улучшить эти сценарии, пожалуйста, оставьте комментарий:)

3 голосов
/ 12 июля 2011

Исправленная версия "То, что вы думали, будет работать":

/usr/share/centrifydc/bin/adcheck --version | sed 's|.*CentrifyDC \([0-9\.]*\).*|\1|'

Выход:

4.4.3
1 голос
/ 12 июля 2011

Другой подход, использующий только awk:

$ echo "adcheck (CentrifyDC 4.4.3-421)" | awk '{sub(/-.*/,"",$3);print $3}'
4.4.3

... или, возможно, комбинация cut:

$ echo "adcheck (CentrifyDC 4.4.3-421)" | cut -d' ' -f3 | cut -d'-' -f1
4.4.3
1 голос
/ 11 июля 2011

Вот решение в Perl:

echo "adcheck (CentrifyDC 4.4.3-421)" | perl -ne 'm/adcheck \(CentrifyDC (.*?)\)/; print "$1\n" '
/usr/share/centrifydc/bin/adcheck --version | perl -ne 'm/adcheck \(CentrifyDC (.*?)\)/; print "$1\n" '
...