Portál AbcLinuxu, 8. května 2025 02:56

Dotaz: linux, bash: porovnani radku v souborech S1 a S2 a nasledna zmena hodnoty v danem soupci v S1

22.8.2017 12:18 nin-ki
linux, bash: porovnani radku v souborech S1 a S2 a nasledna zmena hodnoty v danem soupci v S1
Přečteno: 478×
Odpovědět | Admin
Příloha:
Linux, Bash. Mám dva textové soubory - S1 a S2, které obsahují několik sloupců s písmeny a čísly, formát viz příloha. S2 obsahuje výběr řádků z S1 podle předem daného kritéria. Potřebuji provést operaci porovnání a změny číselné hodnoty v konkrétním sloupci. Tedy, pokud bude souhlasit řádek z S2 s řádkem v S1, resp. čísla ve sloupcích 23-26 budou totožná, tak přímo v souboru S1 se změní číslo z 1.00 na 2.00 ve sloupci 55-60. Změna hodnoty pomocí regulárního výrazu je jasná, ale nevím jak provést porovnání.


Řešení dotazu:


Nástroje: Začni sledovat (1) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

22.8.2017 12:30 NN
Rozbalit Rozbalit vše Re: linux, bash: porovnani radku v souborech S1 a S2 a nasledna zmena hodnoty v danem soupci v S1
Odpovědět | | Sbalit | Link | Blokovat | Admin
Nejdrive bych nacetl data do 2D pole, nebo databaze. Potom si s tim muzes delat co chces.
22.8.2017 13:17 nin-ki
Rozbalit Rozbalit vše Re: linux, bash: porovnani radku v souborech S1 a S2 a nasledna zmena hodnoty v danem soupci v S1
Diky, ale je to pro mne prilis strucne.
22.8.2017 14:34 lertimir | skóre: 64 | blog: Par_slov
Rozbalit Rozbalit vše Re: linux, bash: porovnani radku v souborech S1 a S2 a nasledna zmena hodnoty v danem soupci v S1
Odpovědět | | Sbalit | Link | Blokovat | Admin
Podle mne na komplexnejší změny v souborech (tedy uvnitř nich) bash nebo jiný shell není moc vhodný. Pokud je to skutečně S2 je výběr (tedy inkluzivita a stejné pořadí) tak v jakémkoliv interpretovaném jazyce (python, perl, možná i shelově php) (nebo skriptem do editorů jako vim nebo emacs) , podle toho co umíte, bych procházel po řádcích S2, pak ke každému řádku nalezl přilušný v S1 , v něm provedl změnu a šel dál. Co je cílem? udělat to, protože to potřebuji, nebo udělat to v shellu, protože tě nekdo chce cvičit?
22.8.2017 17:12 nin-ki
Rozbalit Rozbalit vše Re: linux, bash: porovnani radku v souborech S1 a S2 a nasledna zmena hodnoty v danem soupci v S1
Diky. Potrebuju to v ramci zpracovani velkych dat, neni to skolni ukol. Ale take to potrebuju udelat v shellu.
22.8.2017 19:24 Aleš Kapica | skóre: 52 | blog: kenyho_stesky | Ostrava
Rozbalit Rozbalit vše Re: linux, bash: porovnani radku v souborech S1 a S2 a nasledna zmena hodnoty v danem soupci v S1
Proč nevyužiješ standarní unixové nástroje jako je diff, awk, …?
22.8.2017 19:36 Aleš Kapica | skóre: 52 | blog: kenyho_stesky | Ostrava
Rozbalit Rozbalit vše Re: linux, bash: porovnani radku v souborech S1 a S2 a nasledna zmena hodnoty v danem soupci v S1
Jinak mi přijde, že na to jdeš nějak divně. Porovnávat soubor, který zároveň modifikovat? No dobrá, budiž.

Já bych na to šel tak, že bych si vyseparoval z S2 část co se má porovnávat. Pak bych ve smyčce ten výstup zpracovával přes grep, tak aby mi vrátil i číslo řádky s nalezeným vzorkem. A pak bych ten soubor S1 - ještě před tím, než najede smyčka na další záznam - opracoval přes ed.

Jde o to, že je asi žádoucí, aby před hledáním dalšího vzorku byl už soubor S1 modifikovaný, je to tak?
22.8.2017 23:00 lertimir | skóre: 64 | blog: Par_slov
Rozbalit Rozbalit vše Re: linux, bash: porovnani radku v souborech S1 a S2 a nasledna zmena hodnoty v danem soupci v S1
proboha proč? jakékoli výpočetně přijatelné řešení je dobré. Všechno je to interpretovaný soubor, čistý texták a jestli na začátku je #!/bin/bash nebo #!/usr/bin/perl nebo jakýkoliv jiný jazyk je úplně jedno. Stejně na systému perl už obvykle je, protože dost běžných programů jsou perlové skripty. k tomu scriptu, který tady byl už napsán stačí doplnit jen to #!/usr/bin/perl a když umíš jiný jazyk, tak to udělej v něm. shell je na takovou ulohu divny, protože obvykle pracuje (posuzuje, mění) s objekty na filesystemu tedy soubory a adresáři v celku, dovnitř leze jen málo když tak jako logové záznamy a pod. Možná ve spolupráci s awk by to ohnout šlo, ale awk neznám, sice mě periodicky fascinuje jeho uspornost a efektivita, ale nikdy jsem na něj nanašel sílu.
wamba avatar 22.8.2017 14:34 wamba | skóre: 38 | blog: wamba
Rozbalit Rozbalit vše Re: linux, bash: porovnani radku v souborech S1 a S2 a nasledna zmena hodnoty v danem soupci v S1
Odpovědět | | Sbalit | Link | Blokovat | Admin
Řešení v Perlu 6, (které jde napodobit v čemkoliv jiným)
perl6 -e '
    my $S2 = "S2".IO.lines.map( *.substr(23,3) ).Set; 
    for "S1".IO.lines -> $l is copy { 
        NEXT {$l.say}
        next if $l.substr(23,3) ∉ $S2; 
        $l.substr-rw(55,5) = " 2.00";
    }
    '
Z S2 vytáhnu sloupec 23-26 do množiny. Jednotlivé řádky z S1 vytisknu nezměněné pokud nenajdu odpovídající shodu v předešlé množině, nebo cokoliv na 55-60 zaměním za 2.00 a pak vytisknu. Na výstupu dostanu nový S1.
This would have been so hard to fix when you don't know that there is in fact an easy fix.
22.8.2017 17:13 nin-ki
Rozbalit Rozbalit vše Re: linux, bash: porovnani radku v souborech S1 a S2 a nasledna zmena hodnoty v danem soupci v S1
Diky, Perl bohuzel neumim. Princip chapu.
22.8.2017 22:02 RM
Rozbalit Rozbalit vše Re: linux, bash: porovnani radku v souborech S1 a S2 a nasledna zmena hodnoty v danem soupci v S1
Odpovědět | | Sbalit | Link | Blokovat | Admin
Já bych to udělal takhle: S2 i S1 seřadit programem sort -k podle patřičného sloupce a pak krátký one-liner v Awk, který bude číst ze streamu S1. Program si vždy natáhne jeden řádek pomocí getline() z S2 do proměnné a ten bude testovat s každým řádkem (nebo jen částí) přicházejícím ze streamu. Jakmile dojde ke shodě, budou se provádět substituce a to až k první neshodě, pak se načte další řádek z S2, který se dále bude porovnávat v následujících řádcích přicházejících ze streamu z S1, a tak to půjde až do konce souboru S1.
22.8.2017 22:23 RM
Rozbalit Rozbalit vše Re: linux, bash: porovnani radku v souborech S1 a S2 a nasledna zmena hodnoty v danem soupci v S1
Odpovědět | | Sbalit | Link | Blokovat | Admin
Raději ještě uvedu tu ideu s awk pro čtení ze dvou vstupů, což by nemuselo být až tak jasné:

awk '{ if(....) "cat S2.sorted" | getline pattern; (PROGRAM: comp pattern with line-col; substitute;print) }' S1.sorted
Řešení 1× (nin-ki (tazatel))
23.8.2017 15:18 nin-ki
Rozbalit Rozbalit vše Re: linux, bash: porovnani radku v souborech S1 a S2 a nasledna zmena hodnoty v danem soupci v S1
Diky, nakonec jsem na to nejak prisla. Reseni prikladam. Bohuzel tento editor nechce povolit pridani oznaceni pro soubory do skriptu, takze si prosim primyslete za regex soubor1 a za done sobour2.

while read line

do var=$(echo "$line" | cut -c 23-26)

sed -i "/^\(.\{22\}\)\($var\)\(.*\)/s/^\(.\{54\}\)\(......\)\(.*\)/\1 2.00\3/"

done<

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.