줄 내용을 기반으로 파일의 특정 줄을 바꾸는 방법 [닫기]

줄 내용을 기반으로 파일의 특정 줄을 바꾸는 방법 [닫기]

다음과 같은 파일이 있습니다(예는 다음과 같습니다. 파일에는 다음과 같은 줄이 더 많이 포함되어 있습니다).

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_bindsums 에 할당합니다 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. 마지막으로, 나는 얻어야 한다worldmem_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 

이는 부정확할 수 있는 몇 가지 가정을 하고 있다는 점에 유의하십시오(그러나 귀하의 질문으로는 알 수 없습니다).

  1. 그 뒤에 나오는 단어가 sss당신이 관심 있는 단어라고 가정합니다.
  2. 이는 단어가 항상 -하위 단어로 분할된다고 가정합니다.
  3. 단어에는 항상 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}"

그러나 전체 줄을 교체해야 하거나 반대로 단어를 끝에 유지해야 하는 경우에는 댓글로 문의하세요. 쉽게 제공됩니다.

관련 정보