Lägga till en rad med text först i en textfil?

Tråden skapades och har fått 11 svar. Det senaste inlägget skrevs .
1
  • Medlem
  • International user
  • 2005-11-15 14:05

Hur lägger man till en rad FÖRST i en textfil som redan innehåller ett antal rader. Liknade:

echo 'En rad med text' >> $filen

# Lägger ju fint till texten i slutet av filen.
  • Medlem
  • Sollentuna
  • 2005-11-15 15:21
Ursprungligen av Wire:

Hur lägger man till en rad FÖRST i en textfil som redan innehåller ett antal rader. Liknade:

echo 'En rad med text' >> $filen

# Lägger ju fint till texten i slutet av filen.

Svaret är enklare än du tror:

echo 'En ny rad' > temp
cat $filen >> temp
mv temp $filen
  • Medlem
  • International user
  • 2005-11-15 16:37

Måste man exekvera tre program för detta? Går det inte att göra det med ett enda. Eller inom ramen för shellets (bash) redirection?

Och det blir till slut fyra, även 'rm' . Man vill ju städa bort alla tempfiler...

  • Medlem
  • Stockholm
  • 2005-11-15 20:41
Ursprungligen av Wire:

Måste man exekvera tre program för detta? Går det inte att göra det med ett enda. Eller inom ramen för shellets (bash) redirection?

Och det blir till slut fyra, även 'rm' . Man vill ju städa bort alla tempfiler...

Japp, det går inte att skriva i början av en fil utan att skriva sönder det som står där. Du måste alltså skriva en ny fil.

Och du behöver ju inte göra rm eftersom du inte får någon temp-fil kvar efter mv.

  • Medlem
  • International user
  • 2005-11-16 00:05

Jo, det gick utmärkt. Med ett program - 'sed'. Nu är det löst:

Lincoln2:~/test/cat admin$ cat a
rad 1
rad 2
rad 3
Lincoln2:~/test/cat admin$ cat a | sed  '1s/^/Den nya rad 1\
/' > a
Lincoln2:~/test/cat admin$ cat a
Den nya rad 1
rad 1
rad 2
rad 3
Lincoln2:~/test/cat admin$
Ursprungligen av Wire:

Jo, det gick utmärkt. Med ett program - 'sed'. Nu är det löst:

Lincoln2:~/test/cat admin$ cat a
rad 1
rad 2
rad 3
Lincoln2:~/test/cat admin$ cat a | sed  '1s/^/Den nya rad 1\
/' > a
Lincoln2:~/test/cat admin$ cat a
Den nya rad 1
rad 1
rad 2
rad 3
Lincoln2:~/test/cat admin$

Det där är väldigt riskabelt. Du kan inte läsa och skriva till samma fil på en gång. Lite beroende på vilka buffertstorlekar som används och hur stor filen är så kan innehållet försvinna eller förstöras. Det enda säkra sättet är att använda en temporärfil.

  • Medlem
  • Stockholm
  • 2005-11-16 09:48
Ursprungligen av Wire:

Jo, det gick utmärkt. Med ett program - 'sed'. Nu är det löst:

Bortsett från att lösningen (som nämnts ovan) är riskabel så kommer ju även sed att läsa hela filen och skriva ut den. Den gör alltså lika mycket läs/skriv-arbete som den säkra metoden. Så vari ligger fördelen?

Det enda jag kan tänka på är att cat-metoden temporärt använder mer filutrymme. Men om den fil du skall "prependa" till inte är åtskilliga gigabytes stor så är väl det inget problem i en modern disk?

  • Medlem
  • International user
  • 2005-11-16 00:23

Jo ,det finns en fara med just detta. Vet man hur stor bufferten är för t.ex. 'cat'?

Ursprungligen av Wire:

Jo ,det finns en fara med just detta. Vet man hur stor bufferten är för t.ex. 'cat'?

Nej, det vet man inte. Även om man tar reda på exakt under vilka förutsättningar det funkar så är det inte alls säkert att det kommer att bete sig likadant i nästa version. Och man kan vara säker på att det fungerar annorlunda i andra varianter av Unix.

Som sagt, det enda säkra är att alltid använda en temporärfil så slipper man problemet.

  • Medlem
  • International user
  • 2005-11-16 11:02

Metoden med 'sed' ovan borde vara säker. Varken 'cat' eller 'sed' läser ju själva direkt till/från filen. Det är ju 'bash' som förser dessa två med data via std in/out. 'bash' borde ju rimligen inte läsa och skriva samtidigt i samma fil. 'bash' är ju faktiskt ansvarig för hela exekveringsordningen. File I/O -pipe - file I/O.

  • Medlem
  • Stockholm
  • 2005-11-16 16:09
Ursprungligen av Wire:

Metoden med 'sed' ovan borde vara säker. Varken 'cat' eller 'sed' läser ju själva direkt till/från filen. Det är ju 'bash' som förser dessa två med data via std in/out. 'bash' borde ju rimligen inte läsa och skriva samtidigt i samma fil. 'bash' är ju faktiskt ansvarig för hela exekveringsordningen. File I/O -pipe - file I/O.

Jo, cat läser faktiskt direkt från filen och sed skriver direkt i filen. Och bash vet faktiskt inte exakt vad cat gör, hur den använder sitt argument, om det är en fil eller om cat tänker läsa från filen.

Om nu bash skulle vara "ansvarig" (vilket den inte är) så skulle den ju behöva skapa en temporärfil implicit för varje pipe och köra delarna seriellt. Och då skulle ju bash i princip behöva göra allt det som du verkar vilja undvika i cat/temporärfil/mv-lösningen. Mycket ineffektivt. Dessutom skulle bash behöva göra detta i en massa fall som var onödiga för att vara på den säkra sidan. Om nu bash skulle ta allt "ansvar".

Vad vill du uppnå? Vad som GÅR att göra är att skriva ett enkelt C-program som prependar, men detta program skulle fortfarande behöva skriva och läsa hela filen, så det skulle inte gå mycket snabbare än att köra cat/temporärfil/mv.

  • Medlem
  • Stockholm
  • 2005-11-16 16:41
Ursprungligen av pesc:

Vad som GÅR att göra är att skriva ett enkelt C-program som prependar, men detta program skulle fortfarande behöva skriva och läsa hela filen, så det skulle inte gå mycket snabbare än att köra cat/temporärfil/mv.

... fast då jag tänker lite vidare på det så är detta program ingen bra idé. Om programmet eller maskinen skulle krasha under körningen (dra ur sladden!) så kommer filen du arbetar på att bli förstörd. Bästa sättet att undvika det är faktiskt att använda en temporär fil som i den första lösningen.

1
Bevaka tråden