Sök i en fil, ersätt i en annan [LÖST]
-
- Inlägg: 1904
- Blev medlem: 20 jun 2008, 18:09
- OS: Ubuntu
- Utgåva: 12.04 Precise Pangolin LTS
- Ort: Malmö
Sök i en fil, ersätt i en annan [LÖST]
Jag har letat i historien av kategorin, men inte hittat något svar, så jag frågar istället.
Ingress:
Jag skulle behöva söka upp rader i en fil (låt oss kalla den foo.old) efter förekomster utav rader i en annan fil (låt oss, helt otippat, kalla den för foo.new) där början av raden är samma som som i foo.old. Om sådana förekomster hittas skall raden i foo.new ersättas med innehållet i foo.old.
Förklaring:
Jag behöver översätta ett program till svenska, där översättningen görs via en php-fil. Det är en kille som redan har översatt programet, men tyvärr verkar han ha översatt fel fil. Den fil han översatt innehåller (foo.old) en delmängd av de variabler som skall översättas, men inte alla. Jag vill alltså söka upp de strängar han har översatt i foo.old, se om variabeln finns i foo.new och i så fall ersätta hela raden. foo.new är den "riktiga" översättningsfilen och är på engelska, så om det är en variabel han inte översatt så skall den raden baraa hoppas över, så går de att översätta efteråt. Det som skall sökas är alltså php-variabler (alla börjar med $), om det hjälper. Dock kan det finnas mellanslag och tabbar innan variabeln kommer, men de står alltid först på raden.
Detta borde vara enkelt att göra med grep, awk eller sed, men eftersom att jag inte är någon programerare så vet jag inte hur jag skall få ihop det. Det enda jag funnit är ersättning av enskilda ord eller regexp av mönster, men här koan ju mönstren se ut lite hur som helst och skall läsas från en fil. Är det någon som kan hjälpa mig?
Ingress:
Jag skulle behöva söka upp rader i en fil (låt oss kalla den foo.old) efter förekomster utav rader i en annan fil (låt oss, helt otippat, kalla den för foo.new) där början av raden är samma som som i foo.old. Om sådana förekomster hittas skall raden i foo.new ersättas med innehållet i foo.old.
Förklaring:
Jag behöver översätta ett program till svenska, där översättningen görs via en php-fil. Det är en kille som redan har översatt programet, men tyvärr verkar han ha översatt fel fil. Den fil han översatt innehåller (foo.old) en delmängd av de variabler som skall översättas, men inte alla. Jag vill alltså söka upp de strängar han har översatt i foo.old, se om variabeln finns i foo.new och i så fall ersätta hela raden. foo.new är den "riktiga" översättningsfilen och är på engelska, så om det är en variabel han inte översatt så skall den raden baraa hoppas över, så går de att översätta efteråt. Det som skall sökas är alltså php-variabler (alla börjar med $), om det hjälper. Dock kan det finnas mellanslag och tabbar innan variabeln kommer, men de står alltid först på raden.
Detta borde vara enkelt att göra med grep, awk eller sed, men eftersom att jag inte är någon programerare så vet jag inte hur jag skall få ihop det. Det enda jag funnit är ersättning av enskilda ord eller regexp av mönster, men här koan ju mönstren se ut lite hur som helst och skall läsas från en fil. Är det någon som kan hjälpa mig?
Senast redigerad av 1 djkmmo, redigerad totalt 27 gånger.
- Urban Anjar
- Inlägg: 7306
- Blev medlem: 05 nov 2006, 22:59
- OS: Ubuntu
- Utgåva: 22.10 Kinetic Kudu
- Ort: Vickleby
- Kontakt:
Re: Sök i en fil, ersätt i en annan
Har ingen färdig lösning, men diff foo.old foo.new ger i alla fall koll på vilka skillnader det är mellan filerna
-
- Inlägg: 1904
- Blev medlem: 20 jun 2008, 18:09
- OS: Ubuntu
- Utgåva: 12.04 Precise Pangolin LTS
- Ort: Malmö
Re: Sök i en fil, ersätt i en annan
Men diff ger väl svar baserat på radnummer? OM RAD1 != RAD2 SÅ visa?Urban Anjar skrev:Har ingen färdig lösning, men diff foo.old foo.new ger i alla fall koll på vilka skillnader det är mellan filerna
Det kan ju vara väl värt att nämna kanske: radnumret för förekomsterna kan vara helt olika, så $variabel1 kan finnas på rad 563 i foo.old och på rad 1268 i foo.new och $variabel2 kan finnas på rad 1576 i foo.old och på rad 16 i foo.new. Man måste med andra ord (tror jag) söka hela foo.old, rad för rad och jämföra den med hela foo.new, rad för rad.
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
Re: Sök i en fil, ersätt i en annan
Plocka fram de rader du vill ersätta med från filen foo.new... loopa över dem och ersätt i filen foo.old.
-
- Inlägg: 1904
- Blev medlem: 20 jun 2008, 18:09
- OS: Ubuntu
- Utgåva: 12.04 Precise Pangolin LTS
- Ort: Malmö
Re: Sök i en fil, ersätt i en annan
Jo det är ju det jag vill göra, men hur gör jag? Kom i håg att jag inte är ngn programmerare; jag bara vet att det måste vara lätt att göra, men jag vet inte hur man lätt gör detKonservburk skrev:Plocka fram de rader du vill ersätta med från filen foo.new... loopa över dem och ersätt i filen foo.old.

Pretty, pretty please Konservburk, förbarma dig över mig...
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
Re: Sök i en fil, ersätt i en annan
Ge exempel på hur de intressanta raderna kan se ut ...
annars blir det lite svårt för mig att komma med något konkret kod-exempel
annars blir det lite svårt för mig att komma med något konkret kod-exempel

-
- Inlägg: 1904
- Blev medlem: 20 jun 2008, 18:09
- OS: Ubuntu
- Utgåva: 12.04 Precise Pangolin LTS
- Ort: Malmö
Re: Sök i en fil, ersätt i en annan
Aha, visst kan jag göra det. Jag kan t.o.m. göra mer än så, jag kan bifoga filernaKonservburk skrev:Ge exempel på hur de intressanta raderna kan se ut ...
annars blir det lite svårt för mig att komma med något konkret kod-exempel

foo.new:
Kod: Markera allt
$lang_comphire_heading = "Company Hierarchy: Company Information";
$lang_comphire_relationalhierarchy = "Relational Hierarchy";
$lang_comphire_employee = "Employee";
$lang_comphire_definitionlevel = "Definition Level";
$lang_comphire_telephone = "Telephone";
$lang_comphire_fax = "Fax";
$lang_comphire_email = "Email";
$lang_comphire_url = "URL";
$lang_comphire_logo = "Logo";
$lang_comphire_selecthie = "Select Hierarchy";
$lang_comphire_selectdef = "Select Def. Level";
$lang_compstruct_heading = "Company Info : Company Structure";
$lang_compstruct_Dept_Id = "Department ID:";
$lang_compstruct_frmSub_divisionHeadingAdd = "Add a sub-division to";
$lang_compstruct_frmSub_divisionHeadingEdit = "Edit";
$lang_compstruct_Name = "Name";
$lang_compstruct_Type = "Type";
$lang_compstruct_Division = "Division";
$lang_compstruct_Description = "Description";
$lang_compstruct_Department = "Department";
Kod: Markera allt
$lang_Error_PleaseCorrectTheFollowing = "Rätta till följande";
$lang_Error_SelectAtLeastOneRecordToDelete = "Välj minst en uppgift att ta bort";
$lang_Error_DoYouWantToDelete = "Vill du ta bort?";
$lang_Error_EnterDate = "Ange datum?";
$lang_Error_PleaseSelectAYear = "Välj ett år";
$lang_Error_PleaseSelectAnEmployee = "Välj en anställd";
$lang_Error_DoYouWantToContinue = "Vill du fortsätta?";
$lang_Error_PleaseSelectAnEmployee = "Välj en anställd";
$lang_Error_ShouldBeNumeric = "Måste vara numeriskt";
$lang_Error_FollowingErrorsWereFound = "Följande fel hittades";
$lang_Error_AreYouSureYouWantToDelete = "Är du säker på att du vill ta bort";
$lang_Error_AccessDenied = "Åtkomst nekad";
//leave
$lang_Error_PleaseSelectAValidFromDate = "Välj ett giltigt Från-datum";
$lang_Error_PleaseSelectAValidToDate = "Välj ett giltigt Till-datum";
$lang_Error_PleaseSelectALeaveType = "Välj en frånvaroorsak";
$lang_Error_LeaveDateCannotBeABlankValue = "Frånvarodatum kan inte vara ett tomt värde!";
$lang_Error_NameOfHolidayCannotBeBlank = "Namn på semester kan inte vara tomt";
$lang_Error_NoLeaveTypes = "Inga ledighetstyper";
$lang_Error_NoRecordsFound = "Inga uppgifter hittades!";
$lang_Error_InvalidDate = "Ogiltigt datum";
- Bilagor
-
- sv_ver_2.4.1.zip
- (39.79 KiB) Nerladdad 134 gånger
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
Re: Sök i en fil, ersätt i en annan
Kod: Markera allt
sed -n '/^\s*$\S\+\s*=\s*/p' lang_sv_full.php |
(
IFS="=$IFS"
while read a b
do sed -i "s|^\(\s*$a\s*=\s*\).*|\1$b|" lang_default_sv_full.php
done
)
sed -n '/^\s*$\S\+\s*=\s*/p' lang_sv_full.php
Plocka ut rader från lang_sv_full.php som
börjar ^ med
noll eller flera mellanrum \s*
följt av ett dollartecken $
följt av ett eller flera tecken som inte är mellanrum \S\+
följt av noll eller flera mellanrum \s*
följt av ett likhetsteken =
följt av noll eller flera mellanrum \s*
IFS="=$IFS"
Gör så att likhetsteken räknas som mellanrum
while read a b
do ...
done
Loopa över de utplockade raderna och ta i varje varv fram
det som står innan likhetstecknet som $a
och det som står efter likhetstecknet som $b
sed -i "s|^\(\s*$a\s*=\s*\).*|\1$b|" lang_default_sv_full.php
Leta reda på rader från lang_default_sv_full.php som
börjar ^ med
noll eller flera mellanrum \s*
följt av det som stod innan likhetstecknet i den andra filen $a
följt av noll eller flera mellanrum \s*
följt av ett likhetsteken =
följt av noll eller flera mellanrum \s*
och ersätt allt som kommer därefter .* med
det som stod efter likhetstecknet i den andra filen $b
-
- Inlägg: 1269
- Blev medlem: 15 dec 2007, 03:20
- OS: Xubuntu
Re: Sök i en fil, ersätt i en annan
En slags databasoperation. Det finns trevliga unix-kommandon som join och sånt. Ett nätt perl-script som läser old till en hash, uppdaterar hashen med new och sedan skriver ut hashen till newnew kunde ha klarat biffen. Men det finns ett par saker som gör det här lite krångligare.
1) Datat är logisk grupperat. Det är inte säkert att grupperingen är likadan i old och new. Grupperingen är antagligen önskvärd ur underhållssynpunkt. Den kan inte automatåterskapas. Hur bevara ordning i old och new i newnew om de har delvis olika innehåll? Hur bevara tomrader på rätt ställen? Glöm inte kommentarer och att data har "fritt format" (space, tab och i princip newline lite varsomhelst).
2) Datat är inkonsistent. Samma variabel sätts ibland på flera ställen. Ibland till samma värden vilket inte är logiskt fel, men ibland till olika värden. En simpel process kan strunta i det och bara ta första eller sista. Men en människa borde granska dubbleringarna och ta bort eller definiera om den som är minst rätt.
Kommandorad för att upptäcka dubbleringar i en fil:
Lista värdena av dubblerade definitioner:
Variabler som följs av olika [0] och [1] listas av ovanstående kommando men är inte dubbleringar så de är okej. Gå ur less med q.
Fixa 2) så funderar vi andra på en kommandorad som klarar 1).
EDIT: bug i första kommandoraden: andra förekomsten av lang_sv_full.php ska ändras till $i
1) Datat är logisk grupperat. Det är inte säkert att grupperingen är likadan i old och new. Grupperingen är antagligen önskvärd ur underhållssynpunkt. Den kan inte automatåterskapas. Hur bevara ordning i old och new i newnew om de har delvis olika innehåll? Hur bevara tomrader på rätt ställen? Glöm inte kommentarer och att data har "fritt format" (space, tab och i princip newline lite varsomhelst).
2) Datat är inkonsistent. Samma variabel sätts ibland på flera ställen. Ibland till samma värden vilket inte är logiskt fel, men ibland till olika värden. En simpel process kan strunta i det och bara ta första eller sista. Men en människa borde granska dubbleringarna och ta bort eller definiera om den som är minst rätt.
Kommandorad för att upptäcka dubbleringar i en fil:
Kod: Markera allt
for i in lang_sv_full.php lang_default_sv_benefits.php lang_default_sv_full.php; do echo === $i ===; egrep -h -o '\$[a-zA-Z0-9_]+' lang_sv_full.php | sort | uniq -d; done | less
Kod: Markera allt
for i in lang_sv_full.php lang_default_sv_benefits.php lang_default_sv_full.php; do echo === $i ===; egrep -ho '\$[a-zA-Z0-9_]+' $i | sort | uniq -d | tr -d '$' | xargs -i grep -w {} $i; done | less
Fixa 2) så funderar vi andra på en kommandorad som klarar 1).
EDIT: bug i första kommandoraden: andra förekomsten av lang_sv_full.php ska ändras till $i
Senast redigerad av 1 David Andersson, redigerad totalt 17 gånger.
-
- Inlägg: 1269
- Blev medlem: 15 dec 2007, 03:20
- OS: Xubuntu
Re: Sök i en fil, ersätt i en annan
Det är lätt hänt för en männska att missa enstaka engelska rader bland många svenska. Processen (som inte finns än) kan i princip upptäcka och på nåt sätt markera de definitioner den inte ändrat, så att de inte missas efteråt. Det är en lite komplicerande faktor, men kan vara värt det.djkmmo skrev: så om det är en variabel han inte översatt så skall den raden baraa hoppas över, så går de att översätta efteråt.
-
- Inlägg: 1904
- Blev medlem: 20 jun 2008, 18:09
- OS: Ubuntu
- Utgåva: 12.04 Precise Pangolin LTS
- Ort: Malmö
Re: Sök i en fil, ersätt i en annan
Djupa, djupa tackar och många bockar! Fantasktiskt pedagogisk förklaring också. Det här kommer jag att kunna återanvända många ggr. Det är inte helt sällan som folk börjar att översätta något och slutar alt. har översatt en gammal version av programmet, där mycket av den gammla översättningen går att återanvända, men är spridd över filen. Likadant är det ibland en del som tar bort vagnreturer och kommntarer i översättningen, antagligen för att trimma filerna, vilket gör det ännu mer omöjligt att göra arbetet manuellt. Jag får nästa tårar i ögonen nu...Konservburk skrev:Förklaring:Kod: Markera allt
sed -n '/^\s*$\S\+\s*=\s*/p' lang_sv_full.php | ( IFS="=$IFS" while read a b do sed -i "s|^\(\s*$a\s*=\s*\).*|\1$b|" lang_default_sv_full.php done )
sed -n '/^\s*$\S\+\s*=\s*/p' lang_sv_full.php
Plocka ut rader från lang_sv_full.php som
börjar ^ med
noll eller flera mellanrum \s*
följt av ett dollartecken $
följt av ett eller flera tecken som inte är mellanrum \S\+
följt av noll eller flera mellanrum \s*
följt av ett likhetsteken =
följt av noll eller flera mellanrum \s*
IFS="=$IFS"
Gör så att likhetsteken räknas som mellanrum
while read a b
do ...
done
Loopa över de utplockade raderna och ta i varje varv fram
det som står innan likhetstecknet som $a
och det som står efter likhetstecknet som $b
sed -i "s|^\(\s*$a\s*=\s*\).*|\1$b|" lang_default_sv_full.php
Leta reda på rader från lang_default_sv_full.php som
börjar ^ med
noll eller flera mellanrum \s*
följt av det som stod innan likhetstecknet i den andra filen $a
följt av noll eller flera mellanrum \s*
följt av ett likhetsteken =
följt av noll eller flera mellanrum \s*
och ersätt allt som kommer därefter .* med
det som stod efter likhetstecknet i den andra filen $b
Så nu sparar jag det bara och byter ut lang_sv_full.php mot $1 och lang_default_sv_full.php mot $2 för att istället kunna specificera filerna på kommandoraden? Verkligen vackert.
Helt riktigt, även om en del förstör den logiska uppdelningen; se ovan. Med detta går den att återställa igen, till allas fördel.David skrev:1) Datat är logisk grupperat.
Hmmm... Det där är ju inte heller alls dumt. och om man i den första sätter bara en av lang_sv_full.php eller lang_default_sv_benefits.php och använder samma i egrep-delen så får man fram ev. dubletter i filen. För ibland kan det t.o.m. vara så fel. Saker som tillhört en modul flyttas till en annan och så råkar det följa med för mycket när någon klipper och klistrar, så att den variabel deklareras två ggr. i en fil... Eftersom att det handlar om översättningar så är det inte säkert att det syns. Programet kommer ju inte att dö av segmenteringsfel för det. Men det är ju inte så snyggt.David skrev:2) Datat är inkonsistent.
-
- Inlägg: 1904
- Blev medlem: 20 jun 2008, 18:09
- OS: Ubuntu
- Utgåva: 12.04 Precise Pangolin LTS
- Ort: Malmö
Re: Sök i en fil, ersätt i en annan
Nu har jag provat och det fungerade aldeles perfekt, precis som det skulle
.
