두 열의 값을 결합하려면 어떻게해야합니까?


11

다음 형식의 파일이 있습니다.

$ cat /tmp/raw
2015-01   5000   1000
2015-02   6000   2000
2015-03   7000   3000

이제 원하는 것은 결과가 다음과 같이 각 행의 열 2와 3에서 결합 된 값을 얻는 것입니다.

2015-01   6000
2015-02   8000
2015-03   9000

나는 이것을 시도했지만 2015-03 값과 같은 파일의 마지막 값 만 보여줍니다.

답변:


11

당신은 사용할 수 있습니다 awk:

awk '{ print $1, $2 + $3; }' /tmp/raw

결과는 다음과 같습니다 (2015-03의 값이 10000이어야한다고 가정합니다).

2015-01 6000
2015-02 8000
2015-03 10000

1
나는이 빠른 답장을 믿을 수 없어 : O, 나는 다른 포럼에서 그런 빠른 답장을 결코 얻지 못합니다 :) 감사합니다 명령이 완벽하게 작동했습니다 :)
Syed Jahanzaib 2016 년

@SyedJahanzaib,이 답변으로 문제가 해결 되었다면 잠시 후 왼쪽의 확인 표시를 클릭하여 수락하십시오 . 그러면 질문이 답변 된 것으로 표시되며 Stack Exchange 사이트에 감사가 표현되는 방식입니다.
terdon

죄송합니다. 답변을 표시하지 않았습니다. 귀중한 시간과 답장을
보내

@SyedJahanzaib, 나는이 답변에 대한 좋은 배지를 얻었지만 더 정확하고 포괄적 인 것은 terdon의 답변이라고 생각합니다.
taliezin 2016 년

16

몇 가지 방법이 있습니다.

  1. 또 다른 awk 접근법

    awk '{$2+=$3;}NF--' file
    
  2. perl -lane 'print "$F[0] ",$F[1]+$F[2]' file
    

    또는

    perl -ape 's/$F[1].*/$F[1]+$F[2]/e' file
    
  3. 쉘 (위보다 훨씬 느리거나 덜 효율적 임)

    while read a b c; do echo "$a $((b + c))"; done < file
    

2
$2+=$3더 엉망이 될 수 있습니다.
123

실제로 @ User112638726입니다. 감사.
terdon

3
awk '{$2+=$3}NF--'빈 필드 3이 여전히 남아 있지 않도록 사용할 수도 있습니다 . 그것이 저의 선호와 저만의 답변으로 게시하기에는 너무 비슷하지만 :)
123

1
@ User112638726 이제는 나에게도 발생하지 않았습니다. 훨씬 더 깔끔합니다. 감사합니다!
terdon

내가 쓴 당신을 위해. 않는 방법뿐만 아니라 참고 sed어떻게 든 이해하고 관리하는 필드 도 정의 - 필드 즉시, 그리고 필드 에 / w를 필드 - 같은 분명히 경우이지만, 유닉스 정규 표현식 매칭의 전체 개념이되는 사실에 문자열을 분할에 따라 필드 패턴 에 따라 ! 누가 알았 겠어?
mikeserv 2016 년

5
sed 's/[^ ]* */[&]P/;s//&+pc/3'|dc

...인쇄물...

2015-01   6000
2015-02   8000
2015-03   10000

그래서이 선언 상기 정규식 정의 필드 범위 (A)의 구성되어 *가변 길이 문자가 하나의 시퀀스 ^생략 <공간> a로 바로 다음 *가변 길이 문자가 하나의 시퀀스 <공간> . 이 선언은 sed의 패턴 공간에 적용됩니다.이 공간 은 입력시 발생 하는 각 ewline 문자 에 의해 기본적으로 구분되는 문자열 이며 동일한 각 발생에 대해 다음 으로\n 재귀 적으로 대체됩니다 (기본적으로) .

이 선언에 대한 인터페이스는 두 가지이며 각 수준 에서 명령 구문의 예측 가능한 적용을 보장하기 위해 하나 이상의 국제 IEEE 공식 표준위원회 에 의해 완전히 규제되고 지정됩니다 sed. 예를 들어,이 경우 sedAPI 명령 은 /address /명령 (항상 sed s///ubstitution 명령 의 첫 번째 구성 요소 ) 과 함께 적용되지만 내용은 기본 API에 대해 지정된 서브 세트로 더 기본 API에 의해 해석됩니다. 표준 C 라이브러리의regcomp() 함수 .

나는 때문에, 자신이 진술을 할 수 sed있습니다 하지 오히려이 실행 파일 이름이 컴파일 된, 단지 프로그램,하지만 sed내 유닉스와 같은 기계는이다 구현 역사적으로 설립, 잘 정의의, 그리고 표준 제어 sed 응용 프로그램 내 시스템의 regular-의를 식 일치 라이브러리.


로부터 sed사양 :

sed유틸리티는 XBD 기본 정규식에 설명 된 BRE를 지원해야합니다 ...

... 우리가 찾는 곳 ...

BREs 및 ERES 모두에서 POSIX.1-2008의 시스템 인터페이스 볼륨에서 정규 표현식 매칭 인터페이스를 지원하는 regcomp(), regexec()및 관련 기능.

호출하는 응용 프로그램 regcomp()패턴 문자열을 표시하고 ...

... 그 regcomp()함수는 패턴 인수가 가리키는 문자열에 포함 된 정규 표현식을 컴파일 하고 결과를 구조 preg 에 배치해야합니다 .

그에 따라, 상기 응용 프로그램은 regcomp()의 동반자 기능 을 참조 할 것입니다 ...

... [t] 그 regexec()함수에 의해 지정된 널 종료 문자열 비교 문자열 컴파일 된 정규식과 레그 에 대한 이전 호출을 초기화 regcomp()...

... 패턴 의 괄호로 묶인 하위 표현식 에 해당하는 문자열regexec() 하위 문자열의 오프셋으로 [an] 배열의 요소를 채 웁니다 ... 패턴 자체는 하위 표현식으로 계산됩니다 ...\(\)

... 그는 [t] regexec()모두 기입해야 작동 nmatch를 요소 pmatch , nmatch를 하고 pmatch 어떤 요소도, 애플리케이션에 의해 제공되는 pmatch는 에 대응 표현식을하지 않는 패턴 .


그리고 내가 할 때 ...

/[^ ]* */

... sed먼저 정규 표현식을 컴파일 하고 결과를 메모리에 저장 한 다음, 저장된 명령을 자동으로 적용하여 패턴 공간의 내용에 명령을 수행하는 데 필요한 횟수만큼 적용합니다. 결과는로 반환되는 오프셋에서 구분 된 하나 이상의 null로 구분 된 필드 의 배열입니다 regexec().

그리고 내가 할 때 ...

//

...는 가장 최근에 정의 된 정규 표현식을 사용할 필요가 있음을 나타냅니다 sed만 호출 할 수 있습니다 regexec()다시 미리 컴파일 된 정규 표현식을 재사용, 그러나 가능하게 변경된에이 시간을 적용 문자열 인수하거나 새로운 적용 nmatch를 내가 명령으로 매개 변수를.

더 구체적으로 ...

  • s/[^ ]* */[&]P/
    • 패턴 공간에서 처음 나타나는 패턴[왼쪽 대괄호, 그 &다음에 ]오른쪽 대괄호 뒤에 P문자로 바꿉니다.
  • s//&+pc/3
    • 현재 패턴 영역 다시 마지막으로 사용 된 정규식을 적용하고, 대체 3제 3 발생 패턴 과 패턴 영역에 &자체 첨부 문자열 하였다 +pc.

따라서 sed입력 데이터의 각 줄에 대해 예제 데이터가 주어지면 stdout에 씁니다.

[2015-01   ]P5000   1000+pc
[2015-02   ]P6000   2000+pc
[2015-03   ]P7000   3000+pc

이것은 이상하게 보일지 모르지만 dc계산기는 대괄호 사이의 입력에서 문자열 을 인용 하며 P명령은 \newline 을 추가하지 않고 스택 상단을 인쇄 하고 나중에 입력 스택에서 팝을 팝합니다.

따라서 첫 번째 줄을 예로 사용하면 다음과 같이 dc됩니다.

  • [2015-01 ]P
    • P스택의 상단을 찢어 내고 터 뜨리십시오.
  • 5000
    • 숫자 5000를 스택 상단으로 밀고 현재 스택에있는 모든 요소 (현재 없음) 를 1 씩 내립니다.
  • 1000
    • 그러나 이번에는 주 스택 상단의 숫자 5000이 1 씩 내려 가고 스택의 두 번째 요소가됩니다.
  • +
    • 스택에 맨 위 두 숫자를 더하고 스택에서 두 숫자를 모두 빼고 합계를 스택 맨 위로 밉니다.
    • 그 결과 숫자만으로 구성된 스택이 만들어집니다 6000.
    • 스택의 최상위 두 요소 중 하나가 [문자열 인 경우 구문 오류 ]입니다.
  • p
    • p스택 상단에서 \n튀어 나오지 않고 스택 상단을 찢고 추가 된 ewline을 붙 입니다.
  • c
    • c쌓다

나는 그것이 효과가 있다고 생각하지만 파싱 할 수는 없다. 전반적으로 dc에 대한 추가를 설정하고 있습니다. 첫 번째 패턴이 의미가 있습니다. 날짜와 후행 공백과 일치한다고 생각하지만 문자 클래스 대괄호 ([&]) 안에 넣는 내용은 얻지 못합니다. 이걸 철자하면 좋을 것입니다.
Joe

1
@ 조-더 나은가요?
mikeserv 2016 년

와! 그것은 훨씬 더 의미가 있습니다 (그리고 더 많은 것을 알아야 할 많은 것들을 보여줍니다.) 특히, 현재 패턴을 재사용하기 위해 //를 사용하는 것을 보지 못했습니다. 그것은 실제 예제를 실행할 때까지 읽고 잊어 버린 종류입니다. 고마워 그것은 작은 명령에 얼마나 많은 힘이 채워질 수 있는지 그리고 그것을 설명하는 데 얼마나 걸렸는지를보고 웃었습니다.
Joe

@Joe는 - 음 ... 어쩌면 ... 조금 배 밖으로 갔다
mikeserv
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.