Удалите VirtualBox-5.0 и установите VirtualBox-5.1
cut
- неподходящий инструмент для этого. Для манипулирования короткими строками, такими как имена файлов, используйте средства манипулирования строками оболочки, когда это возможно. Все оболочки типа sh¹ (sh, dash, bash, ksh, zsh, ...) имеют некоторые базовые средства работы со строками как часть подстановки переменных. Смотрите, например, руководство по dash в разделе "Расширение параметров". Вы можете удалить самый короткий/самый длинный префикс/суффикс, который соответствует шаблону.
Вам нужна последняя последовательность цифр в имени файла, поэтому:
filename=1.raw_bank_details_211.trg
suffix="${filename##*[0-9]}"
number="${filename%"$suffix"}"
number="${number##*[!-0-9]}"
¹ За исключением некоторых оболочек Bourne до POSIX, но они вас не интересуют.
Вам лучше использовать стандартный инструмент обработки текста вместо наивного инструмента типа cut
.
Вот несколько способов:
С помощью awk
получить _
или .
разделенное второе последнее поле:
awk -F '[_.]' '{print $(NF-1)}' file.txt
grep
с PCRE (-P
):
grep -Po '\d+(?=[^_]*$)' file.txt
-o
получает только совпадающую часть
\d+
совпадает одна или несколько цифр
Положительный заголовок нулевой ширины, (? =[^_]*$)
, гарантирует, что ни один _
не следует до конца строки
С sed
:
sed -E 's/.*_([[:digit:]]+).*/\1/' file.txt
. *_
соответствует всему до последнего _
([[:цифра:]]+)
соответствует нужным цифрам и помещается в захваченную группу
. *
соответствует остальным
При замене используется только захваченная группа, \1
С perl
, логика та же, что и с sed
:
perl -pe 's/.*_(\d+).*/$1/' file.txt
Если вы должны использовать cut
, сделайте это в два шага, сначала получите _
разделенное 4-е поле, а затем получите
разделенное 1-е поле:
cut -d_ -f4 file.txt | cut -d. -f1
Это не рекомендуется, так как требует жесткого кодирования номеров полей.
Если бы это была строка, я бы сделал это с помощью расширения параметров оболочки:
% str='1.raw_bank_details_211.trg'
% str=${str##*_}
% echo "${str%%.*}"
211
Вы можете использовать конструкцию while
и брать каждую строку в переменную и делать это, но это будет медленно для большого файла. Также в качестве альтернативы можно использовать _.
в качестве IFS
и получить вместо этого жестко закодированное поле (например, cut
), если хотите.
Пример:
% cat file.txt
1.raw_bank_details_211.trg
2.raw_bank_details_222.trg
% awk -F '[_.]' '{print $(NF-1)}' file.txt
211
222
% grep -Po '\d+(?=[^_]*$)' file.txt
211
222
% sed -E 's/.*_([[:digit:]]+).*/\1/' file.txt
211
222
% perl -pe 's/.*_(\d+).*/$1/' file.txt
211
222
% cut -d_ -f4 file.txt | cut -d. -f1
211
222