У меня есть файл .img, из которого я хотел бы извлечь 2 значения, полученные с помощью fdisk, в виде строк в 2 переменных.
fdisk -l /home/documents/image-of-sd-card.img
Disk /home/documents/image-of-sd-card.img: 14,84 GiB, 15931539456 bytes, 31116288 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xc680d152
Device Boot Start End Sectors Size Id Type
/home/documents/image-of-sd-card.img1 8192 655359 647168 316M c W95 FAT32 (LBA)
/home/documents/image-of-sd-card.img2 655360 31115263 30459904 14,5G 83 Linux
Значения, которые мне понадобятся, - это последняя единица из «Размер сектора» (512) и конечный размер второго раздела (31115263). Как этого добиться? Я бы предпочел решение на основе Bash, чтобы я мог интегрировать его в существующий сценарий оболочки.
Как абсолютный новичок в Linux, я просто поигрался с некоторыми командами greb, но безрезультатно.
что ты уже испробовал? StackOverflow ожидает, что вы сначала попытаетесь решить свою проблему , так как ваши попытки помогут нам лучше понять, чего вы хотите. Пожалуйста, отредактируйте вопрос, чтобы показать, что вы пробовали, и покажите конкретное препятствие, с которым вы столкнулись, на минимально воспроизводимом примере . Для получения дополнительной информации см. Как спросить.





С установленным fdisk у вас обычно также есть sfdisk, который является «ориентированным на сценарии» fdisk. Вы можете дать ему опцию --json (или -J) для вывода информации в более структурированном формате (попробуйте просто ввести sfdisk -J /path/to/device, чтобы увидеть весь вывод), который затем может быть обработан процессором JSON (например, jq) который может точно извлечь то, что вам нужно. Используйте "$(...)", чтобы захватить вывод и назначить его переменной.
sectorsize = "$(sfdisk -J /path/to/device | jq '.partitiontable.sectorsize')"
part2size = "$(sfdisk -J /path/to/device | jq '.partitiontable.partitions[1].size')"
С большим количеством переменных вы можете объединить вызовы. Вот один пример:
{ read sectorsize; read part2size; } < <(
sfdisk -J /path/to/device | jq '.partitiontable | .sectorsize, .partitions[1].size'
)
Вот пошаговое объяснение, которое поможет вам в изучении bash.
raw_content=$(fdisk -l /home/documents/image-of-sd-card.img)
sector_size=
second_partition_size=
while read i
do
if [[ "$i" == "Sector size"* ]]; then
echo ">>>>$i"
echo "$i" | cut -d ' ' -f 7
sector_size=$(echo "$i" | cut -d ' ' -f 7)
elif [[ "$i" == "/home/documents/image-of-sd-card.img2"* ]]; then
echo ">>>>$i"
echo "$i" | awk -F' ' '{ print $3 }'
second_partition_size=$(echo "$i" | awk -F' ' '{ print $3 }')
fi
done <<< "$raw_content"
echo -e "\nResults:"
echo "sector_size: $sector_size"
echo "second_partition_size: $second_partition_size"
Выход:

raw_content=$(...) сохранит весь вывод в varwhile read i ... done <<< "$raw_content" будет перебирать строку за строкой и устанавливать значение в i varif [[ "$i" == "Sector size"* ]]; спросит, начинается ли строка с ...echo "$i" | cut -d ' ' -f 7 разделит на один пробел и даст вам нужный столбецecho "$i" | awk -F' ' '{ print $3 }' разделит на несколько пробелов и даст вам нужный столбецПотрясающий. Это делает именно то, что мне нужно. Большое спасибо!
Это можно использовать для извлечения размера сектора
size=$(fdisk -l /home/documents/image-of-sd-card.img |awk
'/^Sector/ {print $4}')
Аналогичное сопоставление с образцом можно использовать для извлечения второго требуемого значения.
second_end=$(fdisk -l /home/documents/image-of-sd-card.img |awk
'/^img2/ {print $3}')
В моем случае они не дают никакого результата
Было бы лучше, если бы вы нашли какой-нибудь инструмент, ориентированный на скрипты, например sfdisk,
и будет безопаснее.
В противном случае это можно решить комбинацией grep/sed/owk или даже чистым bash.
fdisk .... > tmpx;
A = "$(
sed -n '\|Sector size (logical/physical)|{ s|.*/ *||; s| *bytes *||; p };' tmpx
)"
B = "$( awk '/sd-card.img2/{print $3}' tmpx )"
echo "The-results---$A---$B---"
The-results---512---31115263---
Пояснения к команде sed: -n говорит не печатать на sed, а p — это команда печати. sed программа запускается по так называемому адресу \| <regular expression> |, который работает как селектор. Следующий блок { ... } выполняется для математических строк и содержит s| <what> | <bywhat>|, где мы просим заменить любой <what> = .*/ * (имеется в виду любой символ (.), повторяющийся произвольно (*), за которым следует косая черта (/), за которым следует пробел () повторяется произвольно (* )).
Мы заменяем <what> на пустую строку. Затем заменяем (s|...|..|)
<what> = «байты» вместе с любыми пробелами. Наконец, мы печатаем (p) результат.
Пояснение к команде awk: Для строк, соответствующих адресу /..../
команда print выполняется для печати третьего $3 слова в строке.
--
Чистый bash раствор:
A = "error"; B = "error";
while read a b c d e f g h ; do
[ "$a,$b,$c,,$e,$f" == "Sector,size,(logical/physical):,,bytes,/" ] && A = "$g";
[[ "$a" == *sd-card.img2 ]] && B = "$c";
done < tmpx;
echo "The-results---$A---$B---"
Примечание: [ ... == ... ] отличается от [[ ... == ... ]].
Какова была ваша попытка? Вы сейчас используете grep, awk и т. д.?