2016-02-25 3 views
0

У меня есть файл под названием sample.txt и значение внутри файлов, как это:сценария оболочки: найти последнее целое число из файла

Примечание редактора: выборочные линии первоначально были пустые строки между ними, но OP с тех пор подтвердил, что это было случайно.

100 
200 
300 
hiiiii 

последнее значение может быть пустой строкой или что-нибудь, кроме числа ....

Как я могу получить последнее целочисленное значение из файла, используя Unix сценарии. выход я жду 300 ..

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

value=`cat $working_tmp_dir/sample.txt|tail -3| head -1|cut -f2 -d'='|cut -b 1-8` 
+0

Какой результат вы хотите, если sample.txt не имеет цифр? –

ответ

3
grep -Eo '^[0-9]+$' hi.txt | tail -1 

где hi.txt ваш файл

0

Этот будет соответствовать номерам в файле и распечатать последний.

grep -o "[0-9]*" sample.txt | tail -n 1

+0

это только улавливает последнюю цифру – Mircea

+0

Вы правы, исправили это. – slugo

+0

все еще не работает для меня – Mircea

2

awk будет хорошо работать здесь:

awk '{ if ($1 ~ /^[0-9]+$/) lastnumber=$1 } END {print lastnumber}' <yourfile.txt> 

awk будет проходить через каждую строку в файл и запустить его через скрипт внутри одиночных кавычек здесь.

Сценарий в терминах непрофессионала говорит: «Проверьте первое поле ($ 1) строки, чтобы увидеть, совпадает ли оно с этим регулярным выражением, которое ищет строку, которая является только числовой. Если она находит совпадение, совпадение в переменной lastnumber.Поскольку awk перемещается вниз по файлу, он меняет lastnumber, когда он находит полностью числовые строки в первом поле. Когда это делается (END), обработка этого файла печатается в переменной lastnumber.

Это означает, что если ваша система поддерживает tac, я бы рекомендовал ответ @ karakfa, поскольку это будет более эффективным для больших файлов.

Я также очень рекомендую прочитать отличный ответ @ mklement0, поскольку он использует эту же логику, но относится ко всей строке файла и является гораздо более сжатым сценарием. Их объяснение очень хорошо сочетается.

+0

Я думаю, что настоящий промах в этом ответе состоит в том, что ему не хватает объяснений о том, что здесь делает 'awk'. Я собираюсь это исправить. Я написал его с неявным 'if' и ссылкой на конкретное поле, потому что это то, что один, а чаще всего и нет, использует' awk', и это хороший опыт обучения для кого-то, кто не знаком с 'awk', который был бы таким же население людей, которые приходят на этот сайт для ответов на вопрос ОП. Рефакторинг вашего сценария до такой степени, что только кто-то, уже знакомый с 'awk', кажется, побеждает цель SO. Но каждому свое. – JNevill

+0

Спасибо за добавление объяснений и за вилку. Я обычно выбираю решение _idiomatic_ и, если возможно, _efficient_, даже если это может быть сложнее понять вначале - вот что дает хорошее объяснение. Те, кому просто интересно готовое решение, не будут заботиться о дидактические аспекты ответа, а тем, кто заинтересован в понимании решения, будет помогать объяснение. – mklement0

+0

Что касается производительности с большими файлами: ответ karakfa будет (потенциально намного) быстрее, чем ближе последний номер в файле к _end_ файла (по сравнению с моим аналогичным решением с коротким замыканием).С меньшими файлами даже ваше решение, которое всегда разбирает строки _all_, может превзойти решение 'tac', особенно с быстрым Awk, таким как' mawk'. – mklement0

0

Другой альтернативный

grep -x '[0-9 ]*' hi.txt | tail -1

(я также решил разрешить пробелы)

+0

не работает для меня (grep (BSD grep) 2.5.1-FreeBSD) – Mircea

2

другая альтернатива

$ tac file | awk '/^[0-9]+$/{print;exit}' 

300 

реверс файл, печать первый номер.

+0

Это замечательно! Я не знал о 'tac'. У кого-то было чувство юмора, называющего это. – JNevill

+1

@JNevill: Обратите внимание, что 'tac' не является утилитой POSIX и что не у всех платформ есть; на BSD/OSX используйте 'tail -r'. – mklement0

+0

Это на моем старом ящике Suse на работе, так что это должно быть довольно распространенным явлением. – JNevill

1

Вы можете использовать GNUgrep команда с -P (PCRE) с -z вариант, который читает весь файл сразу:

grep -oPz '\d+(?=\D*\z)' file 

300 
1

Если предположить, что ваши числа:

  • старт на первой линии
  • все в одном блоке смежных линий

вы можете использовать это эффективное решение одной команды (POSIX-совместимый):

awk '/^[0-9]+$/ { n=$0; next } { print n; exit }' sample.txt 

Примечание: Несмотря на то, karakfa's answer включает дополнительную утилиту, tac, его ответ, вероятно, будет быстрее с большими файлами, у которых последний номер находится близко к концу файла.

  • /^[0-9]+$/ соответствует строке, состоящей только из десятичных цифр, то есть десятичное число (возможно, с ведущими нулями).
  • { n=$0; next } сохраняет эту строку ($0) в переменной n и начинает обработку следующей строки (next; пропускает оставшиеся команды в скрипте).
  • { print n; exit } поэтому сначала выполняется для первой строки, что не состоит только из десятичных цифр; n, который в этот момент содержит последнее десятичное число встречается, печатается, и exit завершает обработку в целом.
+0

пустые строки - это просто проблема форматирования. Между строками нет черных. я попробую это .. спасибо – sarath

+0

файл в конце строки - это мое имя файла? – sarath

+0

@sarath: Правильно. – mklement0

Смежные вопросы