2

After going through a file once, I would like to go back to the beginning of the file and remove entries based on my original pass through the file, but I do not know how to go back to the beginning of the file. I have the name of the input file to the one-liner but not the filehandle. Do I need to have the filehandle? How do I get it from the filename?

Thank you.

  • 1
    Can you show the one-liner? There are several possible ways how to process a file, [seeking](http://p3rl.org/seek) might or might not be possible. – choroba Oct 09 '18 at 21:50
  • my $command = 'perl -pi.bak -e \'my %commits; my @commits_to_delete; my @commits_to_edit; $/="================================================================="; if ($. == 2) { # Deleted code because of character limit. } # I want to go back through the file here. I only work from the first "=================================================================" to the second. } \' RELEASE_LOG_EXAMPLE.bak'; – user2697302 Oct 09 '18 at 22:08
  • 1
    There's no easy way to seek with `-i`. – choroba Oct 09 '18 at 22:14
  • If you are trying to run this oneliner in an existing Perl program, consider using [Path::Tiny's edit_lines_utf8](https://metacpan.org/pod/Path::Tiny#edit_lines,-edit_lines_utf8,-edit_lines_raw) instead, it's similar in implementation and purpose to the perl -i switch. But since you need to seek around [edit_utf8](https://metacpan.org/pod/Path::Tiny#edit,-edit_raw,-edit_utf8) could instead be used to operate on the whole file as a string. – Grinnz Oct 09 '18 at 22:20
  • @choroba I see a concern but it works for me (see answer) – zdim Oct 10 '18 at 00:43
  • You're usually better off just loading the file into memory. – ikegami Oct 10 '18 at 03:19
  • @user2697302: Please don't dump code in a comment like that. It's much better if you [edit your question](https://stackoverflow.com/posts/52729767/edit) to add more information. – Dave Cross Oct 10 '18 at 08:47

1 Answers1

1

The filehandle is ARGV. While -i may raise questions about seeking, it works in my tests

perl -i.bak -pe'
    $_ = "line: $_"; 
    if ($. == 2) { seek ARGV, 0, 0 }
' test.txt

If you see issues with -i or the backup (I don't) run without them and do that manually.

With the -p switch the $_ is printed every time through. Code shown in the comment uses it but the question seems to imply that not every line need be printed, as it wants to "remove entries" from the beginning. If that is the case then use -n instead of -p, which also opens the file and iterates over its lines but does not print. Then add print statements as needed.

It is generally a very good idea to read I/O Operators in perlop, and once you are mucking about with this I'd really recommend it.

It appears that there may be better approaches for your problem but we'd need more detail.

zdim
  • 64,580
  • 5
  • 52
  • 81
  • You can't "unprint" lines printed in the first pass. `-n` will be needed instead. – choroba Oct 10 '18 at 07:37
  • @choroba Right, but they gave `-p` in a comment. I am hoping for feedback. Added a comment, thank you. – zdim Oct 10 '18 at 08:06