배쉬 스크립팅-다음 문자열을 연결하는 방법?


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)이 없는 로컬 변수 만 사용 하여이 작업을 수행하는 방법은 무엇입니까?

답변:


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

당신은 사용하여 중간 파일을 피할 수 파이프를 , 당신은 모두를 사용하여 피할 수 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에 출력이 아닌 2 진 실행 파일의 내용이 지정됩니다.
Joe

0

sed

cpuid | tac | sed '/^CPU/{s/.*//;x;s/\n//g;p;d};/extended \(model\|family\)/!d;s/.*(\(.*\)).*/\1/;H;d'

코어가 8 개인 PC는 다음을 방출합니다.

50  
50  
50  
50  
50  
50  
50  
50  

tac는 CPU 레코드의 종료 자로 ^ CPU를 사용할 수 있도록 cpuid에서 행 순서를 반대로 바꾼 다음 확장 모델 및 확장 패밀리가 올바른 순서로 발생합니다.


0

이것은 초기 명령을 최적화하지는 않지만 세미콜론을 사용하면 연결 작업을 완전히 피하기 위해 두 개의 명령을 함께 사용할 수 있습니다.

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의 첫 번째 줄이 작동하지 않는 이유에 대한 내 의견을 참조하십시오.
Joe
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.