Chtěl bych z daného sloupce (v příkladu 2 $) odstranit duplicitní pole (oddělená čárkou).
Vstupní soubor:
A 1,2,3,4
B 4,5,6,3
C 2,15
Očekávaný výstup:
A 1,2,3,4
B 5,6
C 15
Přijatá odpověď:
perl -lpe 's/sKS+/join ",", grep {!$seen{$_}++} split ",", $&/e'
Výše uvedené můžete spustit takto:
$ perl -lpe 's/sKS+/join ",", grep {!$seen{$_}++} split ",", $&/e' afile
A 1,2,3,4
B 5,6
C 15
Jak to funguje
První volání perl pomocí -lpe dělá následující 3 věci.
-l[octal]povolit zpracování konce řádku, specifikuje zakončení řádku-ppředpokládat smyčku jako -n, ale také tisknout řádek, jako sed-e programjeden řádek programu (je povoleno několik -e, vynechat programový soubor)
Tím se soubor v podstatě přenese dovnitř, odstraní se nové řádky, zpracuje se řádek a poté se na něj připojí znak nového řádku, když je hotovo. Takže je to jen procházení souboru a spouštění našeho kódu v Perlu proti každému v pořadí.
Pokud jde o skutečný kód Perl:
sznamená znak mezery (pět znaků[ fnrt]avv novějších verzíchperl, například[[:space:]]).KPonechte věci vlevo od K, nezahrnujte je do $&S+jeden nebo více znaků není v sadě [ fnrtv]
join ",", převezme výsledky a znovu připojí každé pole tak, aby bylo odděleno čárkou.
split ",", $& vezme shody, které byly nalezeny pomocí S+ a rozdělte je pouze na pole bez čárky.
grep {!$seen{$_}++} vezme číslo každého pole, přidá ho do hash, $seen{} kde číslo každého pole je $_ když procházíme každým z nich. Pokaždé, když je číslo pole „viděno“, je započítáno pomocí ++ operátor, $seen{$_}++ .
grep{!$seen{$_}++} vrátí hodnotu pole, pokud bylo vidět pouze jednou.
Upraveno, aby bylo vidět, co se děje
Pokud použijete tuto upravenou ohavnost, můžete vidět, co se děje, když se tato perlská jedna vložka pohybuje přes řádky ze souboru.
$ perl -lpe 's/sKS+/join ",", grep {!$seen{$_}++} split ",", $&/e; @a=keys %seen; @b=values %seen; print "keys: @a | vals: @b"' afile
keys: 4 1 3 2 | vals: 1 1 1 1
A 1,2,3,4
keys: 6 4 1 3 2 5 | vals: 1 2 1 2 1 1
B 5,6
keys: 6 4 1 3 2 15 5 | vals: 1 2 1 2 2 1 1
C 15
Toto vám ukazuje obsah $seen{} na konci zpracování řádku ze souboru. Vezměme 2. řádek souboru.
B 4,5,6,3
A tady je to, co moje upravená verze ukazuje tento řádek jako:
keys: 6 4 1 3 2 15 5 | vals: 1 2 1 2 2 1 1
Takže to znamená, že jsme viděli pole # 6 (1krát), pole # 4 (2krát) atd. a pole # 5 (1krát). Takže když grep{...} vrátí výsledky, vrátí výsledky z tohoto pole pouze v případě, že byl přítomen v tomto řádku (4,5,6,3) a pokud jsme jej viděli pouze jednou (6,1,15,5). Průnik těchto 2 seznamů je (5,6) a to je to, co vrátí grep .
Odkazy
- perlre – perldoc.perl.org