Как напечатать самое длинное число в строке?

Я ищу метод для печати самого длинного числа в строке.

Например: если у меня есть строка

212334123434test233 

как я могу распечатать

 212334123434 

?

Примечание. Я ищу самую длинную непрерывную последовательность чисел, а не для более высокого значения.


Редактировать: Спасибо за ответы, всем. Ответ на этот вопрос был довольно подавляющим. Я отметил сообщение @ HaukeLaging в качестве принятого ответа, потому что он очень хорошо подходит для моего конкретного случая, но я хотел бы указать, что все ответы одинаково важны. Всегда здорово иметь несколько различных вариантов решения проблемы.

9 Solutions collect form web for “Как напечатать самое длинное число в строке?”

 echo 212334123434test233abc44 | awk '{gsub("[^0-9]+","\n"); print;}' | awk '{ if (length($0) > max) {max = length($0); maxline = $0} } END { print maxline }' 212334123434 

Я считаю, что вы можете сделать это с помощью только grep , sort и tail . Вот несколько примеров строк.

 $ echo <str> | grep -oP "\d+" | sort -n | tail -1 

Где <str> – наша строка под вопросом.

пример

 $ set -o posix; set | grep "str[0-9]" str0=212334123434test233 str1=212334123434test233abc44 str2=233test212334123434 str3=a212334123434test233abc44 str4=a91234b212334123434abc 

Теперь, если я запустил их через мою команду grep ... по очереди.

 $ echo $str0 | grep -oP "\d+" | sort -n | tail -1 212334123434 $ echo $str1 | grep -oP "\d+" | sort -n | tail -1 212334123434 $ echo $str2 | grep -oP "\d+" | sort -n | tail -1 212334123434 $ echo $str3 | grep -oP "\d+" | sort -n | tail -1 212334123434 $ echo $str4 | grep -oP "\d+" | sort -n | tail -1 212334123434 

Этот подход работает, выбирая все подстроки, которые являются последовательностями цифр. Затем мы сортируем этот результат численно, sort -n , а затем берем последнее значение в списке, используя tail -1 . Это будет самая длинная подстрока.

Вы можете увидеть, как это работает, сняв tail -1 и повторив один из примеров:

 $ echo $str4 | grep -oP "\d+" | sort -n 91234 212334123434 

Строки, начинающиеся с нулей

Вышеупомянутый подход работает для любой ситуации, которую я мог бы представить, кроме одного. @terdon упоминает в чате этот сценарий, который лишает вышеупомянутый подход.

  • 0000000000001
  • 2

Поэтому, чтобы справиться с этим, вам нужно немного изменить тактику. Ядро вышеупомянутого подхода все еще можно использовать, однако нам нужно также ввести количество символов в результаты. Это дает возможность сортировать результаты по количеству символов в строках и их значениях.

 $ for i in $(echo $str0 | grep -oP "\d+");do a=$(echo "$i" | wc -c); \ echo "$a $i"; done | sort -n | tail -1 | cut -d" " -f2 

Результаты:

 $ echo $str0 0000000000001a2test $ for i in $(echo $str0 | grep -oP "\d+");do a=$(echo "$i" | wc -c); \ echo "$a $i"; done | sort -n | tail -1 | cut -d" " -f2 0000000000001 

Вы можете сконденсировать это немного, используя способность Bash определять длину переменной, используя ${#var} .

 $ for i in $(echo $str0 | grep -oP "\d+");do echo "${#i} $i"; done | \ sort -n | tail -1 | cut -d" " -f2 0000000000001 

Использование `grep -P

Я решил использовать grep -P ... выше, потому что я, будучи разработчиком Perl, как и синтаксис класса, говоря все такие цифры: \d+ , вместо [[:digit:]]\+ или [0-9]\+ . Но для этой конкретной проблемы это действительно не нужно. Вы могли бы так же легко поменять grep который я использовал так:

 $ .... grep -o "[0-9]\+" .... 

Например:

 $ for i in $(echo $str0 | grep -o "[0-9]\+");do echo "${#i} $i"; done | \ sort -n | tail -1 | cut -d" " -f2 0000000000001 

Решение в perl :

 echo 212334123434test233abc44 | perl -nle 'print (( map { $_->[0] } sort{ $a->[1] <=> $b->[1] } map { [$_,length] } split /\D+/, $_)[-1] )' 212334123434 

Рекомендации

  • Преобразование Шварца

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

 import sys longest = current = "" for x in sys.argv[1]: if current and not x.isdigit(): if len(current) > len(longest): longest = current current = "" else: current += x print(longest) 

Вот еще один подход Perl, который может иметь дело с десятичными знаками, а также целыми числами:

 echo "0.212334123434test233" | perl -lne 'while(/([\d.]+)/g){$max=$1 if length($1) > length($max)} print $max' 

Обратите внимание, что ни один из ответов до сих пор не будет иметь дело с десятичными знаками, и поскольку вы указываете, что вы хотите получить самое длинное, а не численное наибольшее число, я предполагаю, что вам действительно нужны десятичные числа.

объяснение

  • perl -lne : -n означает «читать строки за строкой и запускать скрипт, заданный -e на нем». -l добавляет новую строку для каждого вызова print (и другие вещи, которые здесь не актуальны).
  • while(/([\d.]+)/g) : итерация по всем числам ( \d означает [0-9] , поэтому [\d.] будет соответствовать цифрам и … Если вы также хотите найти отрицательные числа, add - . Скобки заключают согласованную строку как $1 которая используется на следующем шаге.
  • $max=$1 if length($1) > length($max) : если длина текущего совпадения больше самого длинного ( $max ), сохраните совпадение как $max .
  • print $max : напечатать самую длинную строку найденных чисел. Это будет выполнено после завершения цикла while, поэтому после того, как все номера будут найдены.

Данный

 str="212334123434test233" 

затем в bash

 max="" while read num; do (( ${#num} > ${#max} )) && max=$num done < <(grep -Eo '[0-9]+' <<< "$str") echo $max 212334123434 

Возможно, более чистое решение bash, использующее массив, построенный путем замены нецифровых символов в строке пробелом вместо вместо grep

 max="" declare -a nums="${str//[^[:digit:]]/ }" for num in ${nums[@]}; do (( ${#num} > ${#max} )) && max=$num done echo $max 

Основываясь на ответе от @mikeserv, вот еще одна альтернатива. Он извлекает числа (по методу mikeserv), затем сортирует их по порядку и принимает последний. Запрещая ведущие нули, это даст вам наибольшее число (без учета знака):

 echo 1111askdlfm2234 | printf %s\\n $(tr -sc 0-9 \ ) | sort -n | tail -1 

bash и GNU sort

 IFS=$'\0' read -rl _ < <(tr -cs '[:digit:]' '[\0*]' <<<'11abcde1234556ghijk22'| sort -znr) echo $l 1234556 

Используйте нечисловые символы для разделения строки и найдите самую длинную последовательность или наибольшее числовое значение (для чисел с равной длиной) с тройным оператором.

 $ echo "212334123434test233" | awk -F'[^0-9]+' '{for(i=1;i<=NF;i++){m=length($i)>=length(m)||$i>m?$i:m}};END{print m}' 212334123434 

Вы можете также установить разделитель записей awk ( RS ) в любую нечисловую строку символов:

 $ echo "212334123434test233" \ | awk -v RS='[^0-9]+' ' length(longest) < length($0) {longest = $0}; END{print longest}' 212334123434 
  • Заменяйте каждую вкладку ТОЛЬКО в начале каждой строки пробелами
  • grep все строки, начинающиеся с определенного символа, и заканчиваются другим символом
  • Эффективно удалите первую пару строк из текстового файла
  • sed не удаляет символ новой строки
  • Команда Awk / sed для вырезания нескольких разделителей
  • AWK Поиск массивного файла и запись в имя переменной
  • Использование команды внутри подстановки sed
  • Подготовить x / к строке, где x - переменная на каждой строке
  • копировать и вставлять текст с конца строки
  • Как включить все до Colon в Sed / Grep / ...?
  • Найти, если какая-либо строка файла является подмножеством данных в другом файле
  • Linux и Unix - лучшая ОС в мире.