Bash脚本-如何连接以下字符串?


8

这是在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涉及中间文件()来执行此操作?

Answers:


10

一气呵成:

printf '%s%s\n' "$(grep -Pom1 'extended model.*\(\K\d+' <(cpuid))" \
                "$(grep -Pom1 'extended family.*\(\K\d+' <(cpuid))"

上面利用了进程替换(<())和命令替换($())。

  • 用内部命令的STDOUT替换了两个命令替换

  • cpuid将命令放入进程替换中,STDOUT将作为文件描述符返回,grep将对其进行必要的匹配,我们已将grepPCRE(-P)用于仅获取(-o)所需部分,并且-m1在第一次匹配后将停止,以避免重复

  • printf 用于获取所需格式的输出

例:

$ printf '%s%s\n' "$(grep -Pom1 'extended model.*\(\K\d+' <(cpuid))" "$(grep -Pom1 'extended family.*\(\K\d+' <(cpuid))"
30

9

您可以通过使用pipe来避免中间文件,并且可以避免同时使用sedawk通过awk例如进行匹配和替换来避免中间文件。

/usr/bin/cpuid | 
  awk '/extended model/ {mod = substr($4,3)} /extended family/ {fam = substr($4,3)} 
  END {printf "%d%d\n", mod, fam}'

1

在不作任何假设和不改变样本性质的情况下,替换项下降了,该替换项根据要求将输出存储在变量中:

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
I 的输出,然后将变量设置为上一行中设置的变量a的输出(echoCPUID(然后将其通过管道传递给您提供的命令)。


1
谢谢你的解释。这是我最了解的水平。不幸的是,我不是sed,awk和perl的专家,但是我确实有一些初步的了解。:-)
没人

1
cat第一行不应该在那里。它导致为CPUID分配二进制可执行文件的内容,而不是其输出。

0

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用作CPU记录的终止符,然后以正确的顺序出现一个扩展的模型和一个扩展的族。


0

这不会优化您的初始命令,但是分号允许您将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 };)

如果您关心换行符,则需要在开头$(和结尾处加上双引号)


0

这是一种实现方法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
}
'

0

到目前为止,我正在阅读所有评论,我将尝试全部使用它们。正如我写给NGRhodes的信:“不幸的是,我不是sed,awk和perl方面的专家,但我确实有一些初步的理解。

非常感谢所有提供/展示这些出色示例的人。我衷心希望有更多的人阅读这些文章并加深他们的脚本编写技能!

实际上,我做了一些大家都向我建议的鸡尾酒:

/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这是我所期望的!:-)


如果您要执行所有操作并仍然使用awk,则将整个内容重写为一个小的awk程序会更干净。另外,请参阅我对@NGRhodes答案的评论,以了解为什么第一行不起作用。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.