Вот часть bash
выполнение сценария cpuid
исследование в Linux (Ubuntu/Fedora):
/usr/bin/cpuid > id.txt
CPUID=id.txt
echo `grep "extended model" $CPUID` | sed 's/0x//' | awk ' { print $4 } ' > cpu.txt
a=`cat cpu.txt`
echo `grep "extended family" $CPUID`| sed 's/0x//' | awk ' { print $4 } ' > cpu.txt
a+=`cat cpu.txt`
Так, для моего ноутбука эта часть сценария (показанный здесь) дает 60.
Теперь, как сделать этот использующие ТОЛЬКО локальные переменные, не имея промежуточного файла (cpu.txt
) включенный?
Сразу:
printf '%s%s\n' "$(grep -Pom1 'extended model.*\(\K\d+' <(cpuid))" \
"$(grep -Pom1 'extended family.*\(\K\d+' <(cpuid))"
вышеупомянутые рычаги обрабатывают замену (<()
) и управляют заменой ($()
).
две замены команды заменяются STDOUT команд в
cpuid
, команда помещается в замене процесса, STDOUT будет возвращен, поскольку дескриптор файла, grep
сделает необходимое соответствие на нем, мы использовали grep
с PCRE (-P
) для получения только (-o
), желаемая часть, и -m1
остановится после того, как первое соответствие, которое избежит повторения
printf
, используется для получения вывода в нужном формате
Пример:
$ printf '%s%s\n' "$(grep -Pom1 'extended model.*\(\K\d+' <(cpuid))" "$(grep -Pom1 'extended family.*\(\K\d+' <(cpuid))"
30
Можно избежать промежуточного файла при помощи канал , и можно избегать использования и sed
и awk
путем выполнения соответствия и замены в awk
, например,
/usr/bin/cpuid |
awk '/extended model/ {mod = substr($4,3)} /extended family/ {fam = substr($4,3)}
END {printf "%d%d\n", mod, fam}'
Не делая предположений и не меняя природу выборки, вот капля замены, которая сохраняет выходные данные в переменной в соответствии с запросом:
CPUID=$(/usr/bin/cpuid)
a=$(echo "$CPUID" | grep 'extended model' | sed 's/0x//' | awk ' { print $4 } ')
a+=$(echo "$CPUID" | grep 'extended family' | sed 's/0x//' | awk ' { print $4 } ')
Первая строка устанавливает переменную CPUID
для выхода из /usr/bin/cpuid
Затем я устанавливаю переменную a
как выход (echo
) переменной CPUID
, установленной в строке выше (она затем передается по указанным вами командам). [ 118]
sed
cpuid | tac | sed '/^CPU/{s/.*//;x;s/\n//g;p;d};/extended \(model\|family\)/!d;s/.*(\(.*\)).*/\1/;H;d'
, поскольку у меня есть 8 ядер, мой ПК, испускает:
50
50
50
50
50
50
50
50
tac инвертирует порядок строк от cpuid так, чтобы я мог использовать ^CPU в качестве разделителя записи ЦП, также расширенная образцовая и расширенная семья затем происходят в правильном порядке
Это не оптимизирует Ваши начальные команды, но точка с запятой позволяет Вам соединять 2 команды для предотвращения операции конкатенации полностью:
foo="$(firstcommand; secondcommand)"
Или, характерный для Вашей ситуации:
a=$(grep "extended model" $CPUID | sed 's/0x//' | awk ' { print $4 };
grep "extended family" $CPUID | sed 's/0x//' | awk ' { print $4 };)
, Если Вы заботитесь о новых строках, что захотите поместить двойные кавычки перед начальной буквой $(
и после закрытия )
Вот способ сделать это в awk
(весь вывод сделан в соответствии с кодом в вашем ответе).
Когда вы заканчиваете повторную обработку одного и того же ввода снова и снова, это обычно указывает на то, что другой подход может быть лучше.
awk
идеально подходит для такой обработки текста. awk
программы намного длиннее, чем с sed
, но их гораздо легче читать, и вы можете добавить к ним операторы печати, чтобы сделать отладку намного проще.
Я оставил свои отладочные операторы в (закомментированном). Вы можете раскомментировать их, чтобы посмотреть, как работает скрипт.
Вы должны поместить программу awk
куда-нибудь, и самое простое место в одном случае использования, например, это поместить все это в одну строку в кавычках в командной строке awk
.
Таким образом, вам не нужно хранить его в отдельном файле или во временном файле, поэтому управление файлами не требуется, и скрипт будет работать сам по себе.
Эта программа выглядит длинной, но это почти все комментарии, операторы отладки и пробелы.
#!/bin/bash
## Whole awk program is one single quoted string
## on the awk command line
## so we don't need to put it in a separate file
## and so bash doesn't expand any of it
## Debugging statements were left in, but commented out
/usr/bin/cpuid | awk '
BEGIN { ## initialize variables - probably unnecessary
em = ""
ef = ""
fa = ""
mo = ""
si = ""
ps = ""
}
## get each value only once
## extended model is in field 4 starting at the third character
## of a line which contains "extended model"
/extended model/ && em == "" {
em = substr($4, 3)
##print "EM " em
}
## extended family is in field 4 starting at the third character
## of a line which contains "extended family"
/extended family/ && ef == "" {
ef = substr($4, 3)
##print "EF " ef
}
## family is in the last field, starting at the second character
## and is two characters shorter than the field "()"
## of a line which starts with "family"
## (so it does not match "extended family")
$1 == "family" && fa == "" {
##print NF " [" $NF "]"
##print "[" substr($NF, 2) "]"
l = length($NF) - 2
fa = substr($NF, 2, l)
##print "FA " fa
}
## model is in the third field, starting at the third character
## of a line which starts with "model"
## (so it does not match "extended model")
$1 == "model" && mo == "" {
mo = substr($3, 3)
##print "MO " mo
}
## stepping id is in field 4 starting at the third character
## of a line which contains "stepping id"
/stepping id/ && si == "" {
si = substr($4, 3)
##print "SI " si
}
## processor serial number is in field 4 starting at the third character
## of a line which contains "processor serial number:"
/processor serial number:/ && ps == "" {
ps = $4
##print "PS " ps
}
## Quit when we have all the values we need
em != "" && ef != "" && fa != "" && mo != "" && si != "" && ps != "" {
exit
}
END {
print em ef fa mo si " " ps
}
'
До сих пор я читаю все комментарии, и я попытаюсь использовать их всех. Поскольку я записал в NGRhodes: "к сожалению, я не опытен к sed, awk и жемчугу, но некоторой начальной букве, понимая, что я действительно имею.
Большое спасибо всем, кто/представлял эти превосходные примеры. Я искренне надеюсь, что партия больше людей считает эти строки и углубит их навыки сценариев!
На самом деле, я сделал немного коктейля того, что Вы все предложили мне:
/usr/bin/cpuid > id.txt ***[CPUID=$(cat /usr/bin/cpuid) does not work for me]***
CPUID=id.txt
a=$(echo `cat $CPUID | grep -m1 'extended model' | sed 's/0x//' | awk ' { print $4 } '`)
a+=$(echo `cat $CPUID | grep -m1 'extended family' | sed 's/0x//' | awk ' { print $4 } '`)
a+=$(echo `cat $CPUID | grep -m1 'AMD' | sed 's/(//' | sed 's/)//' | awk ' { print $13 } '`)
a+=$(echo `cat $CPUID | grep -m1 'model' | sed 's/0x//' | awk ' { print $3 } '`)
a+=$(echo `cat $CPUID | grep -m1 'stepping id' | sed 's/0x//' | awk ' { print $4 } '`)
a+=' '
a+=$(echo `cat $CPUID | grep -m1 'processor serial number:' | awk ' { print $4 } '`)
echo $a
Результат: 40651 0004-0651-0000-0000-0000-0000 , который является тем, что я ожидаю! :-)