0
votes

Ruby Comment lire un fichier et écrire dans un autre fichier en sautant des lignes

J'ai un fichier .txt que je souhaite copier une partie dans un autre fichier.
Voici ce que le texte ressemble à: xxx

je veux que le nouveau fichier .txt ressemble à xxx

Comment puis-je supprimer la ligne Numéro et la ligne vide et concaténer les lignes avec «bonne» information
Comment puis-je faire ça?


1 commentaires

Vous nous demandez d'écrire le code pour vous? Ou, avez-vous écrit le code et vous ne nous êtes-vous pas montré? Voir " Liste de contrôle de la question de pile " et " Écrire la question parfaite "


3 Réponses :


1
votes
File.open("output.txt", "w") do |file_to_write|
  File.open("input.txt").each do |line|
    if $. % 4 == 2
      file_to_write.write(line.chomp)
    end
    if $. % 4 == 3
      file_to_write.write(line)
    end
  end
end
Ruby has a special symbol which will give you the line number $. you can substitute that with File.open(filename).each_with_index do |line, index| and use index instead of $.. 
If you use an index you will need to add 1 to it, because it will start off at 0.This code goes through your input file line-by-line. The lines starting from the second and third line and then each following line of interest is offset by 4. 
Once we find the first half write that line to our opened file without a new line, once we find the second half (second if statement) write that line with a line terminator to the file.

2 commentaires

Suivi index_for_first_half semble inutile lorsque vous pouvez faire $. % 4 == 2 et $. % 4 == 3 , respectivement. En outre, pourquoi utiliser impression un en ligne et écrire de l'autre? Ils sont équivalents dans ce cas.


Vous êtes correct, je mettrai à jour ma réponse. J'étais sous l'hypothèse qui imprime des impressions sans un caractère \ N au fichier contrairement à écrire.



1
votes

Construisons le fichier d'entrée. 1 sup> xxx pré>

h1>

p> xxx pré>

Nous pouvons lire ce fichier à quatre lignes à la fois et pour chaque groupe de quatre lignes, écrivez une seule ligne dans le fichier de sortie, où la ligne unique est construite à partir des deuxième et troisième lignes de chaque groupe de quatre lignes. P> xxx pré>

Confirmons que le fichier de sortie a été construit correctement. p> xxx pré>

J'ai utilisé la méthode IO :: foreach Pour lire le fichier d'entrée ligne-ligne. (Cela devrait être votre méthode Go-to Cotation pour la lecture de fichiers texte en ligne). Vous pouvez voir depuis foreach code> soc que la méthode a deux formes, une avec un bloc et un sans. J'ai utilisé ce dernier, qui retourne un énumérateur, parce que je veux la chaîner à la méthode énumérable # chaque_slice . p>

Voyons comment ces énumérateurs fonctionnent. P>

r =
/
^         # match the beginning of a line
\d{2}:    # match two digits followed by a colon
.+?       # match one or more characters lazily
(?=\n\n)  # the match is to be followed by two newlines
/mx       # multiline and free-spacing regex definition modes


0 commentaires

3
votes

Ils le font semblent si durs ...

de Ruby's foreach code> a la possibilité de recevoir un séparateur de ligne en tant que second paramètre: p> xxx pré>

si vous passez "\ n \ n" code> Ruby retournera plusieurs lignes séparées par une ligne vide. Cela facilite la lecture d'un fichier, tel que le vôtre. P>

Utilisation de vos données d'entrée enregistrées dans un fichier et exécuté ce code dans le même répertoire: P>

require 'fruity'

test_file = <<EOT
1
00:00:00 :  
renovation with a fully
EOT

test_file.gsub(/\A\d+|\n/, '')               # => "00:00:00 :  renovation with a fully"
test_file.lines[1, 2].map(&:chomp).join      # => "00:00:00 :  renovation with a fully"
'%s%s' % test_file.lines[1, 2].map(&:chomp)  # => "00:00:00 :  renovation with a fully"

compare do
  cary { test_file.gsub(/\A\d+|\n/, '') }
  ttm1 { test_file.lines[1, 2].map(&:chomp).join }
  ttm2 { '%s%s' % test_file.lines[1, 2].map(&:chomp) }
end

# >> Running each test 4096 times. Test will take about 1 second.
# >> ttm1 is similar to ttm2
# >> ttm2 is faster than cary by 2x ± 0.1

__END__
1
00:00:00 :
renovation with a fully


5 commentaires

Une variante est fichier.foreach (fname_in, "\ n \ n") {| chunk | met chunk.gsub (/ \ a \ d + | \ n /, '')} . Mamesaye, voir String # GSUB . L'expression régulière se lit comme suit: «Faites correspondre un ou plusieurs chiffres ( \ d + ) au début de la chaîne ( \ a ) ou ( | ) correspondre à une nouvelle ligne ( \ n ). gsub convertit ces chaînes assorties aux chaînes vides (c.-à-d. Il renvoie une chaîne avec les chaînes assorties supprimées). Par exemple, quand Chunk est égal à "1 \ n00: 00: 00: \ nRenovation avec un entièrement \ n \ n" , '1' au début de la chaîne Et les quatre personnages Newline sont assortis ...


... donc gsub renvoie "00:00:00: rénovation avec un" entièrement ".


Utilisation gsub et un motif fonctionnera plus lentement. Il passe de la simple manipulation de chaîne à des expressions régulières. En fonction de l'exécution particulière, le fruité me dit le gsub et le motif est jusqu'à 2x plus lent. J'ai déjà vu cela avant et habituellement l'ancrage aidera, mais je pense que le suppléant | le ralentit. Peut-être qu'un modèle plus complet aidera.


J'ai ajouté deux lignes à votre Comparer bloc: sub_delete {test_file.sub (/ \ a \ d + /, '') .Delete ("\ n")} et < Code> substr_delete {test_file [test_file.index ("\ n") ..- 1] .Delete ("\ n")} . Je l'ai couru plusieurs fois. Ce qui suit est indiquant le résultat moyen: "SubR_Delete est similaire à TTM1, TTM1 est similaire à Sub_Delete, Sub_Delete est similaire à TTM2, TTM2 est plus rapide que Cary par 2x ± 0,1".


N'hésitez pas à mettre à jour ma réponse avec le code de référence et les résultats. Il est toujours bon de voir comment les différentes méthodes et façons de faire des choses affectent la vitesse. Regex ne devez pas être plus lent, mais dans ce cas, où il y a de nombreux sauts dans le moteur et que je pense qu'ils vont courir plus lentement. Ce qui serait exécuté le plus rapide aurait de prétraiter les numéros de ligne à l'aide d'un motif en un seul passage, puis de traverser et de reconstruire les lignes.