다음과 같은 파일이 있습니다(예는 다음과 같습니다. 파일에는 다음과 같은 줄이 더 많이 포함되어 있습니다).
first line sss case-2-hello-world other words
second line other words
third line sss case-1-love-you other words
fourth line other words
fifth line other words
sixth line sss case-6-not-work other words
나는 그것을 다음과 같이 변환하고 싶습니다 :
pp:12 pme:4 plan:cpu_bind=hello mem_bind=world
second line other words
pp:6 pme:2 plan:cpu_bind=love mem_bind=you
fourth line other words
fifth line other words
pp:36 pme:12 plan:cpu_bind=not mem_bind=work
먼저 패턴이 있는 선을 식별합니다 sss
. 둘째, 숫자를 추출합니다. 셋째, pp와 pme를 계산합니다 pp=number*6 and pme=number*2
. 넷째, 숫자가 포함된 줄의 단어를 분할하여 cpu_bind
sums 에 할당합니다 mem_bind
. 다섯째, 함께 모아서 라인을 교체합니다.
예를 들어, 나는 라인을 식별합니다
first line sss case-2-hello-world other words
에 대한 sss
숫자는 2입니다. 그 후에는 계산을 해야 합니다 pp=2*6 pme=2*2
. 문자열을 case-2-hello-world
여러 부분 으로 나누고 합계 hello
에 할당합니다 cpu_bind
. 마지막으로, 나는 얻어야 한다world
mem_bind
pp:12 pme:4 plan:cpu_bind=hello mem_bind=world
원래 줄을 교체하십시오.
참고: sss
줄의 어느 곳에나 나타날 수 있지만 한 번만 나타납니다. sss
교체해야 하는 행을 식별하는 데 사용할 수 있는 유일한 패턴입니다. 줄에는 숫자와 다른 숫자를 포함하는 다른 단어가 있습니다. 패턴은 case-number-cpu_bind-mem_bind
네 부분으로 구성됩니다. 그 순서는 정해져 있어 뱉어낼 수 있다 -
.
답변1
Python(2.x)에서:
import sys
pat = 'sss'
for line in open(sys.argv[1]):
if not pat in line:
print line,
continue
case_nr = line.split(pat + ' case-', 1)[1].split('-')[0]
print '**something about case{}**'.format(case_nr)
부르다python script_name.py input.txt > output.txt
답변2
사용에 문제가 없다면 sed
:
sed 's/\(.*\)sss case-\([0-9]*\)-.*/something about case\2/' input.txt
답변3
이것은 너무 복잡하므로 이를 수행하려면 완전한 프로그래밍 언어를 사용하겠습니다. 예를 들어 Perl에서는 다음과 같습니다.
$ perl -ne 'if(/\ssss\s+/ && /(\S+-\d+-\S+)/){
@F=split(/-/,$1);
print "pp:",
6 * $F[1],
" pme:",2*$F[1],
" plan:cpu_bind=$F[2] mem_bind=$F[3]\n"
}else{print}' file
또는 약간의 골프를 치되 동일한 아이디어를 따르십시오.
$ perl -lpe '/\ssss\s+/&&do{/(\S+-\d+-\S+)/;@F=split(/-/,$1);
$_="pp:".6*$F[1]." pme:".2*$F[1]." plan:cpu_bind=$F[2] mem_bind=$F[3]"}' file
이는 부정확할 수 있는 몇 가지 가정을 하고 있다는 점에 유의하십시오(그러나 귀하의 질문으로는 알 수 없습니다).
- 그 뒤에 나오는 단어가
sss
당신이 관심 있는 단어라고 가정합니다. - 이는 단어가 항상
-
하위 단어로 분할된다고 가정합니다. - 단어에는 항상 4개의 부분이 있다고 가정합니다.
case
첫 번째 부분은 숫자이고 두 번째 부분은 숫자이며cpu_bind
합계에 할당되어야 하는 두 단어가 있습니다mem_bind
.
이러한 가정이 정확하다고 가정하면 이는 스크립트에 주석을 추가하는 것과 같습니다.
#!/usr/bin/env perl
## Read the input file line by line
while (<>) {
## If this line matches whitespace (\s), then "sss", then one
## or more whitespace character, identify the string of interest
## by looking for non-whitespace characters (\S+), "-", then
## numbers (\d+), then "-" and more non-whitespace characters and
## save them as $1.
if(/\ssss\s+/ && /(\S+-\d+-\S+)/){
## Split the word captured above into the @F array
## by cutting it on "-"
@F=split(/-/,$1);
## Start printing.
print "pp:",
## 6 * the 2nd element in the array (the number)
6 * $F[1],
" pme:",2*$F[1],
## The third element ($F[2]) is the 1st word
## and the fourth element ($F[3]) is the 2nd word.
" plan:cpu_bind=$F[2] mem_bind=$F[3]\n"
}
## If this line does not match "sss", print it.
else{print}
}
답변4
제가 이해한 대로 설명하면 다음과 같습니다.
sed "/sss/{s/case1.*$/$case1;s/case2.*/$case2;s/case3.*/$case3}"
그러나 전체 줄을 교체해야 하거나 반대로 단어를 끝에 유지해야 하는 경우에는 댓글로 문의하세요. 쉽게 제공됩니다.