Jak połączyć wartości z dwóch kolumn?

11

Mam plik w następującym formacie:

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

Teraz chcę uzyskać połączoną wartość z kolumn 2 i 3 w każdym wierszu, aby wyniki były następujące:

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

Próbowałem tego, ale pokazuje tylko ostatnią wartość w pliku, taką jak wartość 2015-03.

Syed Jahanzaib
źródło

Odpowiedzi:

11

Możesz spróbować użyć awk:

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

Wynik będzie (Przypuszczam, że wartość dla 2015-03 powinna wynosić 10000):

2015-01 6000
2015-02 8000
2015-03 10000
taliezin
źródło
1
Nie mogę uwierzyć, że dostałem odpowiedź tak szybko: O, nigdy nie otrzymuję tak szybkiej odpowiedzi na żadnym innym forum :) dziękuję, polecenie zadziałało idealnie :)
Syed Jahanzaib
@SyedJahanzaib, Jeśli ta odpowiedź rozwiązała problem, poświęć chwilę i zaakceptuj go , klikając znacznik wyboru po lewej stronie. To oznacza pytanie jako odpowiedź i jest to sposób wyrażania podziękowań na stronach Stack Exchange.
terdon
przepraszam, zapomniałem zaznaczyć odpowiedź. i dziękuję wszystkim innym za cenny czas i odpowiedzi, pomogli mi również w nauce osiągania celów inną metodą :)
Syed Jahanzaib
@SyedJahanzaib, chociaż zdobyłem niezłą odznakę za tę odpowiedź, myślę, że bardziej precyzyjna i wyczerpująca jest odpowiedź terdona.
taliezin
16

Oto kilka sposobów:

  1. Kolejne podejście awk

    awk '{$2+=$3;}NF--' file
    
  2. Perl

    perl -lane 'print "$F[0] ",$F[1]+$F[2]' file
    

    lub

    perl -ape 's/$F[1].*/$F[1]+$F[2]/e' file
    
  3. Shell (znacznie wolniejszy / mniej wydajny niż powyższe)

    while read a b c; do echo "$a $((b + c))"; done < file
    
terdon
źródło
2
$2+=$3może być bardziej niesamowity.
123
@ User112638726 rzeczywiście tak jest. Dzięki.
terdon
3
Możesz także użyć, awk '{$2+=$3}NF--'aby nie wisiało puste pole 3. Chociaż to tylko moja preferencja i jest zbyt podobna, by pisać jako odpowiedź sama w sobie :)
123
1
@ User112638726 teraz, że mi się nawet nie przyszło do głowy. O wiele fajniejsze, dzięki!
terdon
Napisałem to dla ciebie. Zauważ, że nie tylko w sedjakiś sposób udaje się zrozumieć pola - nawet zdefiniować pola w locie i pola w / w polach - ale, jak się wydaje, cała koncepcja dopasowywania wyrażeń regularnych w systemie Unix opiera się na podzieleniu łańcucha na pola według wzoru ! Kto wiedział?
mikeserv
5
sed 's/[^ ]* */[&]P/;s//&+pc/3'|dc

... drukuje ...

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

Tak więc powyżej deklaruję wyrażenie regularne, które definiuje zasięg pola, który składa się z pojedynczej sekwencji znaków o *zmiennej długości , które ^nie<spacja>, po której następuje bezpośrednio pojedyncza sekwencja znaków o *zmiennej długości, <p> . Ta deklaracja jest stosowana do sedprzestrzeni wzorców, która jest łańcuchem ograniczonym (domyślnie) każdym \nznakiem ewline występującym na wejściu, i który jest rekurencyjnie zastępowany (domyślnie) następnym dla każdego wystąpienia tego samego.

Interfejs tej deklaracji jest dwojaki, a na każdym poziomie jest w pełni regulowany i określony przez co najmniej jedną międzynarodową oficjalną komisję normalizacyjną IEEE, aby zapewnić przewidywalne stosowanie sedskładni poleceń. Na przykład sedskładnia API jest stosowana w tym przypadku do polecenia /adresowego (które zawsze jest pierwszym składnikiem każdego polecenia ubstitution) , ale jego treść jest interpretowana przez bardziej podstawowy interfejs API jako podzbiór tego określonego dla parametru funkcja w standardowej biblioteki C ./sed s///regcomp()

Mogę wypowiadać te stwierdzenia pewnie, ponieważ niesed jest to tylko program, ale raczej skompilowany plik wykonywalny nazwany sedna mojej maszynie podobnej do Uniksa jest implementacją dobrze zdefiniowanej, historycznie ustalonej i kontrolowanej przez normy sed aplikacji regularnego systemu biblioteki dopasowujące wyrażenia.


Ze sedspecyfikacji:

sedNarzędzie wspiera BRES opisane w XBD podstawowych wyrażeń regularnych ...

... gdzie znajdujemy ...

Oba BRES i Eres są obsługiwane przez interfejs Regular Expression Matching wolumenu systemu interfejsów POSIX.1-2008 mocy regcomp(), regexec()oraz funkcji związanych.

Aplikacja, która domaga regcomp()się przedstawić wzór ciąg i ...

... regcomp()funkcja ta skompiluje wyrażenie regularne zawarte w ciągu wskazanym przez argument wzorca i umieści wyniki w strukturze preg ...

Aby zareagować na to, wspomniana aplikacja będzie odnosić się do regcomp()funkcji pomocniczej ...

... [t] regexec()funkcja porównuje łańcuch zakończony znakiem null określony przez łańcuch ze skompilowanym wyrażeniem regularnym preg zainicjowanym przez poprzednie wywołanie regcomp()...

... regexec()wypełnia elementów [an] tablicy z przesunięciami podciągi z ciągu znaków , które odpowiadają \(nawiasach podwyrażeń \)na wzór ... wzór sama liczy się jako podwyrażenie ...

... [t] regexec()funkcja musi wypełnić wszystkie elementy nmatch w pmatch , gdzie nmatch i pmatch są dostarczane przez aplikację, nawet jeśli niektóre elementy pmatch nie odpowiadają podwyrażeniom wzorca .


I kiedy to zrobię ...

/[^ ]* */

... sednajpierw kompiluje wyrażenie regularne i przechowuje wyniki w pamięci, a następnie stosuje zapisany tam skompilowany automat do zawartości mojej przestrzeni wzorcowej tyle razy, ile jest to konieczne do wypełnienia mojego polecenia. Za każdym razem, gdy tak się dzieje, wynikiem jest tablica jednego lub więcej pól rozdzielanych zerami, które są rozdzielane przy odsunięciu przez regexec().

A kiedy to zrobię ...

//

... aby wskazać, że należy użyć ostatnio zdefiniowanego wyrażenia regularnego, sedmoże po prostu wywołać regexec()ponowne użycie wstępnie skompilowanego wyrażenia regularnego, ale możliwe, że zastosuje go tym razem do zmienionego argumentu ciągu lub zastosuje nowe parametry nmatch jako polecenie.

A dokładniej jeszcze ...

  • s/[^ ]* */[&]P/
    • zamień pierwsze wystąpienie wzoru w przestrzeni wzorów na [lewy nawias kwadratowy, potem na &siebie, potem na ]prawy nawias kwadratowy, po którym następuje Pznak.
  • s//&+pc/3
    • zastosuj ostatnio użyte wyrażenie regularne ponownie do bieżącej przestrzeni wzorca i zastąp 3trzecie wystąpienie wzorca w przestrzeni wzorca &, a po nim dołączony ciąg +pc.

I tak dla każdego wiersza sedwejścia zapisuje na standardowe wyjście, biorąc pod uwagę twoje przykładowe dane:

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

Może to wyglądać dziwnie, ale dckalkulator cytuje łańcuchy w danych wejściowych między nawiasami kwadratowymi, a Ppolecenie zarówno wydrukuje górę stosu bez dołączania \newline, jak i następnie usunie go ze stosu wejściowego.

I tak, używając pierwszego wiersza jako przykładu, dczrobi:

  • [2015-01 ]P
    • Print i pop na szczycie stosu
  • 5000
    • Wciśnij liczbę 5000na wierzch stosu i popchnij wszystkie elementy znajdujące się obecnie na stosie (teraz żaden) o jeden.
  • 1000
    • to samo, ale tym razem liczba 5000 na górze głównego stosu zostaje przesunięta o jeden i staje się drugim elementem na stosie.
  • +
    • Dodaj do siebie dwie górne liczby ze stosu, usuń obie ze stosu i wsuń sumę na szczyt stosu.
    • Daje to stos składający się tylko z liczby 6000.
    • Jest to błąd składniowy, jeśli jeden z dwóch górnych elementów na stosie jest [ciągiem ].
  • p
    • pprzeglądnij górę stosu, a następnie dołączoną \newline bez wyskakiwania z niego ze stosu.
  • c
    • cpoznaj stos
mikeserv
źródło
Wierzę, że to działa, ale nie mogę tego przeanalizować. Ogólnie rzecz biorąc, konfigurujesz dodatek do DC. Pierwszy wzór ma sens. Myślę, że pasuje do daty i końcowych spacji, ale nie rozumiem, co robi to w nawiasach klasowych znaków ([&]). Byłoby wspaniale, gdybyś przeliterował to.
Joe
1
@Joe - jest coś lepszego?
mikeserv
Łał! Ma to o wiele większy sens (i pokazuje mi wiele rzeczy, o których muszę się więcej dowiedzieć.) W szczególności nigdy nie zauważyłem użycia // do ponownego użycia obecnego wzorca. Tego rodzaju rzeczy czytasz i zapominasz, dopóki nie natrafisz na prawdziwy przykład. Wielkie dzięki. Rozśmieszyłem się, widząc, ile mocy można było upakować w maleńkim poleceniu i ile trzeba było, żeby to wyjaśnić.
Joe
@Joe - cóż ... może poszedłem trochę za burtę ...
mikeserv