Как получить эту подстроку в сценарии bash?

Я заметил, что некоторые версии Linux не позволяют использовать файловые системы ext4 в качестве каталога /boot. Я полагаю, что именно поэтому во многих системах Linux вы увидите разметку, подобную следующей:

 /dev/sda1 -- /boot ext3 -- about 1GB
 /dev/sda2 -- SWAP -- 1* memory but could be smaller
 /dev/sda3 -- /  ext4 -- The rest of the disk

Это также позволяет разделу / быть не ext4 разделом... например, btrfs, zfs или xfs, которые, скорее всего, не совместимы с grub.

В частности, это проблема RHEL 5/Centos 5.

4
15.10.2016, 08:02
6 ответов

С расширением параметра bash:

$ var='tSA_15_20161014_11-12-50'

$ var="${var#*_}"  ## Extracts the portion after first `_` i.e. 
                      new `var` will be `15_20161014_11-12-50`

$ var="${var#*_}"  ## again gets the portion after first `_`, so in this case
                      after operation `var` will contain `20161014_11-12-50`

$ echo "${var//[-_]/}"  ## Replaces all `-` and `_` from `$var` with null
20161014111250
12
27.01.2020, 20:44
echo "tSA_15_20161014_11-12-50" | awk -F'_' '{print $3$4}' | tr -d -

echo var, в котором хранится строка

Объяснение:

awk -F'_' '{print $3$4}' измените разделитель полей на _ и распечатайте 3-й и 4-й столбец

Выходные данные будут 2016101411-12-50

tr -d - удаляет - из предыдущего результата.

8
27.01.2020, 20:44

Для полноты, несколько версий sed :

echo "tSA_15_20161014_11-12-50" \
| sed -rn 's/^tSA_[0-9]{1,3}_([0-9]{8})_([0-9]{2})-([0-9]{2})-([0-9]{2})$/\1\2\3\4/p'

echo "tSA_15_20161014_11-12-50" \
| sed -r 's/^tSA_[0-9]{1,3}_([0-9]{8})_([0-9]{2})-([0-9]{2})-([0-9]{2})$/\1\2\3\4/'

echo "tSA_15_20161014_11-12-50" \
| sed -r 's/([^_]*_){2}(.*)_(.*)/\2\3/;s/-//g'

echo "tSA_15_20161014_11-12-50" \
| sed -r 's/(.*_){3}/\1/;s/[-_]//g'

Одна вещь, которую я считаю важной, - это проверка ошибок. В случае, если переменная не соответствует точно указанному вами формату, первая версия выдаст пустую строку, а вторая версия выдаст входную строку без изменений. Третья версия - это sed версия ответа @ debal awk , а четвертая настолько лаконична, насколько я могу легко ее получить, обе без определенного поведения при неправильном вводе.

2
27.01.2020, 20:44

Given

var='tSA_15_20161014_11-12-50'

then

IFS=_ read -a arr <<< "${var//-/}"
printf '%s%s\n' "${arr[2]}" "${arr[3]}"
20161014111250
3
27.01.2020, 20:44

Другой awk подход. Поскольку awk может принимать несколько символов в качестве разделителей полей, это можно сделать за один шаг:

$ awk -F'[-_]' '{print $3$4$5$6}' <<<"$var"
20161014111250

В качестве альтернативы в Perl:

$ perl -pe 's/.+?_.+?_//; s/[-_]//g' <<<"$var"
20161014111250

или

$ perl -F_ -ane 's/-//g for @F; print @F[2..$#F]' <<<"$var"
20161014111250

Я использую здесь строки , но если ваша оболочка их не поддерживает, просто echo $ var | command для каждой команды выше.

2
27.01.2020, 20:44

Решение Python, использующее re.split () с несколькими токенами. Строка ввода предоставляется как аргумент командной строки

$ python -c 'import sys,re;print("".join(re.split("[-_]",sys.argv[1])[2:]))' "tSA_15_20161014_11-12-50"
20161014111250

Аналогичный подход с ruby:

$ ruby -ne 'puts $_.split(/[-_]/)[2..-1].join("")' <<<  "tSA_15_20161014_11-12-50"                                                   
20161014111250
0
27.01.2020, 20:44

Теги

Похожие вопросы