Заполнение массива именами дисковых томов в OSX — пробелами

Прямо сейчас я использую команду ниже, чтобы получить имена томов подключенных дисков в OSX:

$exec = "df -lH | grep \"/Volumes/*\" | tr -s \" \" | sed 's/ /;/g'";

И анализируя вывод, используя этот код:

$lines = explode("\n", $output);
$i = 0;
foreach ($lines as $line) {
$driveinfo = explode(";", $line);
$driveinfo[7] = trim($driveinfo[0]);
if (!empty($driveinfo[0]))
$allremovabledrives[$driveinfo[0]] = $driveinfo;
$i++;
}

Это прекрасно работает, если в метке тома нет пробелов:

[/dev/disk1s1] => Array
(
[0] => /dev/disk1s1
[1] => 32G
[2] => 31G
[3] => 674M
[4] => 98%
[5] => 0
[6] => 0
[7] => /dev/disk1s1
[8] => /Volumes/LUMIX
)

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

[/dev/disk4] => Array
(
[0] => /dev/disk4
[1] => 4.0T
[2] => 1.2T
[3] => 2.8T
[4] => 29%
[5] => 140741078
[6] => 347553584
[7] => /dev/disk4
[8] => /Volumes/My
[9] => Passport
[10] => Pro
)

Кто-нибудь может помочь мне решить эту проблему? Я не очень разбираюсь в утилитах sed и командной строки …

1

Решение

ОК, имя тома всегда является последним полем, и вы знаете, сколько их полей (9), поэтому я бы просто разделил пробел и запросил столько полей. И не заморачивайся sed/awk/grep/tr вещи, так как вы уже находитесь в полноценной системе программирования, которая может делать то, что эти команды делают более эффективно в своем собственном пространстве процессов.

Во-первых, вы можете передать список томов, информацию о которых вы хотите получить. df в качестве аргументов, что означает, что вам не нужно grep:

$df = shell_exec('df -lH /Volumes/*');

Теперь разделите на новую строку и избавьтесь от заголовков:

$rows = explode("\n", $df);
array_shift($rows);

Начните строить свой результат:

$result = array();

Здесь нам не нужно использовать утилиты оболочки, чтобы сделать возможным explode что мы уже можем сделать с preg_split, Регулярное выражение /\s+/ соответствует 1 или более пробельным символам в строке, поэтому мы не получаем дополнительные поля. Предел (9) означает, что он разбивается только на 9 полей независимо от того, сколько еще пробелов — таким образом, пробелы в последнем поле (имя тома) остаются одни.

foreach ($rows as $row) {
$cols = preg_split('/\s+/', $row, 9);
$result[$cols[0]] = $cols;
}

После всего этого, $result должен выглядеть так, как вы хотите.

1

Другие решения

Других решений пока нет …