Ответ на другую половину вопроса, на том, почему это происходит: часы Компьютерного оборудования известно неточны, поэтому в то время как дрейф 12 секунд за день необычен, это не действительно все что необычный.
(Это, вероятно, из-за распространенности использования сетевого времени, так, чтобы дрейф даже 12 секунд в день был незначительным раздражением по сравнению с тем, чем это было бы в часах - и таким образом компании-производители оборудования могут использовать дешевые микросхемы синхрогенератора. Физически, что происходит, вероятно, что осциллятор в Вашей микросхеме синхрогенератора не калибруется совершенно верно, таким образом, это работает немного-но-надежно медленный.)
Использовать ${VAR%PATTERN}
удалить суффикс, соответствующий последнему полю, затем ${NEWVAR##PATTERN}
удалить префикс, соответствующий всем кроме последнего остающегося поля.
all_but_last_field=${mystring%.*}
second_to_last_field=${all_but_last_field##*.}
Необходимо сохранить строку в переменной и сохранить промежуточный результат в переменной также, Вы не можете непосредственно объединить расширения в цепочку (Вы можете в zsh, но не в ударе).
С чистым bash
:
IFS='.' read -a p <<< 'foo_1.103.1.0.release_32_xx.ver21-inc-1'
echo "${p[${#p[@]}-2]}"
Можно сделать это легче с awk
:
awk -F. '{print$(NF-1)}' <<< 'foo_1.103.1.0.release_32_xx.ver21-inc-1'
В случае, если Ваши строки для парсинга являются именами файлов, можно все еще сделать это с awk
:
awk -F. 'BEGIN{for(i=1;i<ARGC;i++){$0=ARGV[i];print$(NF-1)}}' foo*
+1
для самого лучшего ответа. Ваш echo
было бы более хорошим таким образом: echo "${p[@]:(-2):1}"
.
– gniourf_gniourf
27.12.2012, 12:30
A sed
команда, чтобы сделать это:
sed 's/foo_[0-9.]*\([^.]*\).*/\1/' inputfile
Принятие, конечно, это inputfile
содержит Ваши строки, каждого на его собственной строке (поскольку Ваш пример, кажется). Если говорят, что Вы используете имена файлов, то, передавая результаты по каналу ls
в sed
будет работать также.
[0-9.]
его слабость – перестанет работать на имени файла как “foo_1.103b.debug_xx.ver21-inc-1”. Лучше положитесь строго на точки: sed 's/.*\.\([^.]*\)\.[^.]*$/\1/'
.
– manatwork
27.12.2012, 17:15
принятие их является файлами:
нечто ls* | awk-F. '{Печатают 3$}'
ls
основанное решение отобразилось бы “de\bug_xx”. Это может быть исправлено с ls
--quoting-style=literal
. Но если имена файлов содержали бы новую строку, парсинг был бы, стал более сложным. установка
– manatwork
27.12.2012, 12:56
second_to_last_field=${all_but_last_field##*.}
. Я принимаю Ваш ответ, поскольку это - чистый удар, но ответ Drake Clarris был большим также. Это на самом деле еще более компактно, но я могу только выбрать 1 ответ. Спасибо парни :) – icasimpan 28.12.2012, 02:56