以下是在 Linux(Ubuntu/Fedora)中bash
执行发现的脚本部分:cpuid
/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
)?
答案1
一气呵成:
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
答案2
您可以使用管道,您可以通过在例如中进行匹配和替换来避免同时使用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}'
答案3
在不做假设和改变样本性质的情况下,这里是一个替代方案,它根据要求将输出存储在变量中:
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
为 I 的输出/usr/bin/cpuid
,然后将变量设置a
为上面一行中设置的变量的输出(echo
)CPUID
(然后通过管道传输到您提供的命令)。
答案4
这不会优化您的初始命令,但是分号允许您将 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 };)
如果你关心换行符,你需要在首字母前$(
和结尾字母后加上双引号)