Именование файлов с помощью десятичных чисел в BASH

Предположим, я беру строку типа:

can cats eat plants?

Использование жадного оператора c.*sбудет соответствовать всей строке, поскольку она начинается с cи заканчивается s, будучи жадным оператором, он продолжает соответствовать до последнего вхождения s.

В то время как использование ленивого c.*?sбудет соответствовать только до тех пор, пока не будет найдено первое вхождение s, то есть строка can cats.

Из приведенного выше примера вы можете понять, что:

"Жадный" означает соответствие максимально длинной строке. «Ленивый» означает сопоставление самой короткой строки. Добавление ?к квантификатору, такому как *, +, ?или {n,m}, делает его ленивым.

0
12.05.2020, 11:58
3 ответа

Непросто выполнять арифметические (сложения, вычитания, умножения и т. д. )с плавающими числами в оболочке.

Но большинство оболочек могут печатать числа с плавающей запятой:

$ for i in $(seq 0.10 0.1 0.9); do printf '%5.3f  ' "$i"; done
0.100  0.200  0.300  0.400  0.500  0.600  0.700  0.800  0.900

Что станет:

$ for i in $(seq 0.10 0.1 0.9); do printf 'slipped_112_111_%5.3f.vasp\n' "$i"; done
slipped_112_111_0.100.vasp
slipped_112_111_0.200.vasp
slipped_112_111_0.300.vasp
slipped_112_111_0.400.vasp
slipped_112_111_0.500.vasp
slipped_112_111_0.600.vasp
slipped_112_111_0.700.vasp
slipped_112_111_0.800.vasp
slipped_112_111_0.900.vasp

Для выполнения математических операций в оболочке требуется bc или awk.

$ printf '%5.3f" "$(echo "0.3321 + 0.3625" | bc -l)"
0.695


0
28.04.2021, 23:14

Оболочка bashне выполняет арифметические операции с плавающей запятой.

Это означает, что вы не можете использовать значения с плавающей запятой так, как хотите. Вместо этого вы можете использовать

for number in {1..9}; do
    # other code here

    printf -v name 'slipped_112_111_0.%d0.vasp' "$number"
    mv POSCAR "$name"
done

Оператор printf -vпечатает прямо в переменную name. Строка формата форматирует число так, чтобы оно находилось в правильном месте в имени вашего нового файла.

Это приведет к выполнению следующих mvкоманд:

mv POSCAR slipped_112_111_0.10.vasp
mv POSCAR slipped_112_111_0.20.vasp
mv POSCAR slipped_112_111_0.30.vasp
mv POSCAR slipped_112_111_0.40.vasp
mv POSCAR slipped_112_111_0.50.vasp
mv POSCAR slipped_112_111_0.60.vasp
mv POSCAR slipped_112_111_0.70.vasp
mv POSCAR slipped_112_111_0.80.vasp
mv POSCAR slipped_112_111_0.90.vasp

Если вам нужны числа с плавающей запятой для чего-то еще:

for number in {1..9}; do
    # other code here

    value=$( bc <<<"scale=2; $number/20" )

    printf -v name 'slipped_112_111_0.%d0.vasp' "$number"
    mv POSCAR "$name"
done
2
28.04.2021, 23:14

Нет необходимости выполнять десятичную арифметику :создавать строки.

В любом случае ваш пример изменяет только одну цифру. Более общая версия:

paul $ for i in {010..200..10}; do
> echo "${i:0:1}.${i:1:2}"
> done
0.10
0.20
0.30
0.40
0.50
0.60
0.70
0.80
0.90
1.00
1.10
1.20
1.30
1.40
1.50
1.60
1.70
1.80
1.90
2.00
0
28.04.2021, 23:14

Теги

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