Учитывая имя файла в форме someletters_12345_moreleters.ext
, я хочу извлечь 5 цифр и поместить их в переменную.
Итак, чтобы подчеркнуть это, у меня есть имя файла с числом символов х, затем пятизначной последовательностью, окруженной одним подчеркиванием с обеих сторон, а затем другим набором из числа символов х. Я хочу взять 5-значный номер и поместить его в переменную.
Меня очень интересует количество различных способов достижения этой цели.
abc_12345_def_67890_ghi_def
действительный вход. Что ты хочешь случиться? Давайте предположим, что есть только одна последовательность из 5 цифр. У вас все еще естьabc_def_12345_ghi_jkl
или1234567_12345_1234567
или12345d_12345_12345e
как действительный ввод, основанный на вашем определении ввода, и большинство ответов ниже не справятся с этим._
разделитель, ввод, который содержит целевую строку только один раз и т. Д.). Лучший (самый общий и самый быстрый) ответ имеет, после 10 лет, только 7 upvotes, в то время как другие ограниченные ответы сотни. Заставляет меня терять веру в разработчиков 😞Ответы:
Используйте вырезать :
Более общий:
источник
echo
если только вы не уверены, что переменные не могут содержать нерегулярные пробелы или метасимволы оболочки. См. Подробнее stackoverflow.com/questions/10067266/…Если x является константой, следующее расширение параметра выполняет извлечение подстроки:
где 12 - смещение (от нуля) и 5 - длина
Если подчеркивания вокруг цифр являются единственными на входе, вы можете удалить префикс и суффикс (соответственно) в два этапа:
Если есть и другие подчеркивания, это возможно в любом случае, хотя и более сложно. Если кто-нибудь знает, как выполнить оба расширения в одном выражении, я бы тоже хотел знать.
Оба представленных решения являются чисто bash, без порождения процессов, а значит, очень быстрыми.
источник
bash: ${${a#*_}%_*}: bad substitution
на моем GNU bash 4.2.45.sh
сценарии, который, вероятно, был чертой. На данный момент я не могу заставить его работать больше.:-
замену «Использовать значения по умолчанию». Таким образом,${a: -12:5}
получается 5 символов 12 символов от конца и${a: -12:-5}
7 символов между концом-12 и концом-5.Общее решение, где число может быть где угодно в имени файла, используя первую из следующих последовательностей:
Другое решение для извлечения именно части переменной:
Если ваше имя файла всегда имеет формат,
stuff_digits_...
вы можете использовать awk:Еще одно решение, чтобы удалить все, кроме цифр, используйте
источник
просто попробуйте использовать
cut -c startIndx-stopIndx
источник
startIndx-$((lastIndx-1))
start=5;stop=9; echo "the rain in spain" | cut -c $start-$(($stop-1))
git log --oneline | head -1 | cut -c 9-(end -1)
line=
git log --oneline | head -1` && echo $ line | cut -c 9 - $ (($ {# line} -1)) `, но в данном конкретном случае лучше использовать sed asgit log --oneline | head -1 | sed -e 's/^[a-z0-9]* //g'
В случае, если кто-то хочет получить более точную информацию, вы также можете найти ее в man bash следующим образом.
Результат:
источник
${var: -4}
Вот как я бы это сделал:
Объяснение:
Bash-конкретно:
[[ ]]
указывает на условное выражение=~
указывает, что условие является регулярным выражением&&
Цепочка команд, если предыдущая команда была успешнойРегулярные выражения (RE):
_([[:digit:]]{5})_
_
литералы для разграничения / привязки границ сопоставления для сопоставляемой строки()
создать группу захвата[[:digit:]]
это класс персонажей, я думаю, это говорит само за себя{5}
означает, что ровно пять из предшествующего символа, класса (как в этом примере) или группы должны совпадатьВ английском языке вы можете думать, что он ведет себя так:
FN
строка повторяется символ за символом, пока мы не увидим,_
в какой момент группа захвата открыта, и мы не попытаемся сопоставить пять цифр. Если это сопоставление прошло успешно, группа захвата сохраняет пять пройденных цифр. Если следующий символ -_
, условие выполнено успешно, группа захвата становится доступнойBASH_REMATCH
, иNUM=
может выполняться следующий оператор. В случае сбоя какой-либо части сопоставления сохраненные данные удаляются, а посимвольная обработка продолжается после_
. например, еслиFN
где_1 _12 _123 _1234 _12345_
, было бы четыре фальстарта, прежде чем он нашел совпадение.источник
cut
). Это также не зависит от выполнения внешней команды.Я удивлен, что это чистое решение bash не подошло:
Вы, вероятно, хотите сбросить IFS до того значения, которое было до или
unset IFS
после!источник
IFS
и позиционные параметры:IFS=_ read -r _ digs _ <<< "$a"; echo "$digs"
Опираясь на ответ Джора (который не работает для меня):
источник
cut
ли.Следуя требованиям
Я нашел несколько
grep
способов, которые могут быть полезны:или лучше
И затем с
-Po
синтаксисом:Или, если вы хотите, чтобы в нем было ровно 5 символов:
Наконец, чтобы сохранить его в переменной, просто нужно использовать
var=$(command)
синтаксис.источник
Invocation as 'egrep' is deprecated; use 'grep -E' instead
. Я отредактировал твой ответ.Если мы сосредоточимся на понятии:
« последовательность (одна или несколько) цифр»
Мы могли бы использовать несколько внешних инструментов для извлечения чисел.
Мы могли бы легко стереть все другие символы, как sed, так и tr:
Но если $ name содержит несколько серий чисел, вышеперечисленное завершится ошибкой:
Если «name = someletters_12345_moreleters_323_end.ext», то:
Нам нужно использовать регулярные выражения (регулярное выражение).
Чтобы выбрать только первый запуск (12345, а не 323) в sed и perl:
Но мы могли бы сделать это прямо в bash (1) :
Это позволяет нам извлечь ПЕРВЫЙ набор цифр любой длины,
окруженный любым другим текстом / символами.
Примечание :
regex=[^0-9]*([0-9]{5,5}).*$;
совпадет только с 5-значными прогонами. :-)(1) : быстрее, чем вызывать внешний инструмент для каждого короткого текста. Не быстрее, чем вся обработка внутри sed или awk для больших файлов.
источник
Без каких-либо подпроцессов вы можете:
Очень маленький вариант этого также будет работать в ksh93.
источник
Вот решение с префиксом-суффиксом (аналогично решениям JB и Darron), которое соответствует первому блоку цифр и не зависит от окружающих подчеркиваний:
источник
Мне нравится
sed
способность иметь дело с группами регулярных выражений:Несколько более общий вариант был бы не предположить , что у вас есть подчеркивание
_
маркировки начала ваших цифр последовательности, поэтому, например , вырежет все не-номер вы получите до вашей последовательности:s/[^0-9]\+\([0-9]\+\).*/\1/p
.Подробнее об этом, если вы не слишком уверены в регулярных выражениях:
s
для _s_ubstitute[0-9]+
соответствует 1+ цифр\1
ссылки на группу №1 вывода регулярного выражения (группа 0 - это полное совпадение, группа 1 - это совпадение в скобках в этом случае)p
флаг для _p_rintingВсе побеги
\
есть, чтобы заставитьsed
работать обработку регулярного выражения.источник
Мой ответ будет иметь больше контроля над тем, что вы хотите от вашей строки. Вот код о том, как вы можете извлечь
12345
из вашей строкиЭто будет более эффективно, если вы хотите извлечь что-то, что имеет какие-либо символы, например,
abc
или какие-либо специальные символы, такие как_
или-
. Например: если ваша строка такая, и вы хотите все, что послеsomeletters_
и до_moreleters.ext
:С моим кодом вы можете упомянуть, что именно вы хотите. Объяснение:
#*
Это удалит предыдущую строку, включая соответствующий ключ. Здесь ключ, который мы упомянули_
%
, удалит следующую строку, включая соответствующий ключ. Здесь ключ, который мы упомянули, «_more *»Сделайте несколько экспериментов самостоятельно, и вы найдете это интересным.
источник
Данный test.txt представляет собой файл, содержащий «ABCDEFGHIJKLMNOPQRSTUVWXYZ»
источник
Хорошо, здесь идет чистая замена параметров с пустой строкой. Предостережение заключается в том, что я определила someletters и moreletters только как символы. Если они буквенно-цифровые, это не будет работать, как есть.
источник
аналогично substr ('abcdefg', 2-1, 3) в php:
источник
Также есть встроенная команда bash expr:
источник
expr
не является встроенным=~
оператора, поддерживаемого[[
.Немного поздно, но я просто наткнулся на эту проблему и обнаружил следующее:
Я использовал его для получения разрешения в миллисекундах во встроенной системе, в которой нет даты% N на дату:
источник
Решение Bash:
Это закроет переменную с именем
x
. VARx
может быть изменен на VAR_
.источник
Инклюзивный конец, похожий на реализации JS и Java. Удалить +1, если вы не хотите этого.
Пример:
Больше примеров звонков:
Добро пожаловать.
источник