17 votes

Ajouter une seule ligne au fichier avec Ruby

J'aimerais ajouter une seule ligne en haut d'un fichier avec Ruby, comme ceci :

# initial file contents
something
else

# file contents after prepending "hello" on its own line
hello
something
else

Le code suivant remplace simplement le contenu de l'ensemble du fichier :

f = File.new('myfile', 'w')
f.write "test string"

2voto

Gaurav Manchanda Points 132

Vous pouvez essayer ceci :

File.copy_stream(myfile,tempfile)
f = File.open(myfile,'w')
f.write("Hello\n#{File.open(tempfile,'r').read}")
f.close
File.delete(tempfile)

0voto

ThorX89 Points 967

Depuis la ligne de commande, vous pouvez le faire :

ruby -i -pe '$_= "prepended text\n"+$_ if $. == 1' myfile

ou plus efficacement

ruby -i -pe 'BEGIN { gets; print "prepended text\n" + $_ }; ' myfile

Malheureusement, il s'avère que le -i (in-place) n'est pas vraiment in-place, cependant (tout comme l'option sed ) - mon fichier aura un inode différent après l'opération.

Cela m'a rendu triste, parce qu'effectivement, je ne peux pas filtrer un énorme fichier si je n'ai pas assez d'espace disque pour en faire deux copies.

Il n'est pas vraiment difficile de le faire en place, cependant (filtrage en général, pas seulement pour la première ligne). Il suffit de faire ce qui suit :

1) Assurez-vous que vous avez des pointeurs de lecture et d'écriture séparés (ou des objets File séparés pour la lecture et l'écriture). 2) assurez-vous que vous avez mis en mémoire tampon les parties non lues que vous allez réécrire. 3) tronquez le fichier à la fin si votre opération de filtrage doit aboutir à un fichier plus court.

J'ai écrit une classe wrapper pour cela à https://github.org/pjump/i_rewriter .

Avec lui, vous pouvez faire

Rewriter.new("myfile") do |line, index|
  index == 0 ? "prepended text\n" + line : line
end

ou avec l'exécutable :

$  i_rewriter 'index == 0 ? "prepended text\n" + line : line' myfile

Utilisez-le avec précaution (il peut corrompre votre fichier s'il est interrompu).

0voto

deman_killer Points 48

Pure, mais qui fonctionne. Minimisez les opérations liées aux fichiers.

`#!/bin/ruby
inv_file = File.open("./1.txt","r+") { |f|
    #Read file string by-string
    until f.eof?
        #Searching for some
        if f.readline[/condition here/]
            #remember position
            offset = f.pos
            #Find it? - stop reading
            break
        end
    end
    #Remember what contains rest of file
    tail = f.readlines
    #Again to offset
    f.pos = offset
    #insert what necessary
    f.puts "INSERTED"
    #reconstruct tail
    f.write tail.join
    }`

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X