Skrypt powłoki: chwyć ciąg znaków w środku tekstu, czasem na początku

9

Mam duży plik tekstowy, w którym jego część wygląda tak (wartości edytowane):

JULIANA XXXX006060 LI1033322 THC BRL 730.00
XXXX006296 AA1004737 THC BRL 1,740.00
SANTOS JULIANA XXXX006668 AA1004786 THC BRL 8,150.00
SANTOS JULIANA CABINDA XXXX006697 AA1004777 THC BRL 2,325.00
SANTOS JULIANA XXXX006699 AA1004790 THC BRL 2,325.00
JULIANA BATA XXXX006141 CCC012946 THC BRL 1,460.00
JULIANA BATA XXXX006153 CCC013054 THC BRL 870.00
JULIANA XXXX006269 CCC013105 THC BRL 870.00
JULIANA XXXX006295 CCC013083 THC BRL 870.00
JULIANA BATA XXXX006305 CCC013043 THC BRL 1,460.00

Chcę zawsze chwytać (za pomocą cutlub awkinnego) ciąg, który zaczyna się od XXXX00, ale nigdy nie ma tego samego numeru pola.

Jak mogę to zrobić w skrypcie powłoki?

Vitor Gatti
źródło

Odpowiedzi:

12

Po prostu grepdla tego:

grep -oE 'XXXX00[0-9]*' file
  • -o: Drukuje tylko pasującą część.
  • -E: Aktywuje rozszerzone wyrażenia regularne.
  • [0-9]*: Po ciągu do wyszukiwania powinny się pojawiać tylko cyfry.
chaos
źródło
Zauważ, że regex nie potrzebuje tej -Eopcji (choć nie szkodzi).
Jonathan Leffler
6

Wygląda na to, że chcesz 5. pola z prawej strony, więc

awk '{print $(NF-4)}' file
Glenn Jackman
źródło
tak!
mikeserv
3

Korzystanie grepz PCRE:

% grep -Po '(^|\s)\KXXXX00[^\s]*(?=(\s|$))' file.txt
XXXX006060
XXXX006296
XXXX006668
XXXX006697
XXXX006699
XXXX006141
XXXX006153
XXXX006269
XXXX006295
XXXX006305

Możesz uciec -w(słowo) w tym przypadku, pamiętaj, że znaki składowe słowa są uważane za [[:alnum:]_]:

% grep -wo 'XXXX00[^ ]*' file.txt
XXXX006060
XXXX006296
XXXX006668
XXXX006697
XXXX006699
XXXX006141
XXXX006153
XXXX006269
XXXX006295
XXXX006305
heemayl
źródło
2

Kilka innych sposobów

Z GNU awk

awk -vRS='[[:space:]]+' '/^X{4}0{2}/' file

W przypadku starszych wersji GNU awk, --re-intervalmogą być potrzebne, więc

awk --re-interval -vRS='[[:space:]]+' '/^X{4}0{2}/' file

Z trigrep

<file tr -s '[:space:]' '[\n*]' | grep '^X\{4\}0\{2\}'
iruvar
źródło
1
sed 's/[^0]*  *\([^ ]*\).*/\1/' <in >out

wygląda na to, że liczby pól są różne, ponieważ masz tam listę osób i mają one różną liczbę nazwisk. ale prawdopodobnie żaden z nich nie ma nazwy z 0, więc po prostu odetnij całkowicie pierwszy łańcuch rozdzielany spacjami z jednym w nim, zapisz go i wytnij wszystko, co następuje.

mikeserv
źródło