2

I'm running Windows 10 and I have a batch file that changes the directory to the required location and a perl command that edits all text files in it by changing Enabled = 1 to Enabled = 0, but I can't figure out how to make the perl command check for subfolders.

@echo off
timeout 1 >nul 2>&1
cd /d D:
timeout 1 >nul 2>&1
cd "D:\MySettings"
timeout 1 >nul 2>&1
perl -wE "@ARGV = glob qq($ARGV[0]); $^I = qq(); while (<>) { s/Enabled =\K.*/ \x220\x22/g; print }" *.txt
Pause
LG Zana
  • 103
  • 5
  • 1
    You are trying to emulate the functionality of `-p -i`, the edit-in-place combo. But why not just use the switches directly? If it's about the globbing, just put that in a `BEGIN` block. – TLP Aug 08 '22 at 08:31
  • 1
    [`File::Find`](https://perldoc.perl.org/File::Find) is a core module that allows you to traverse folders recursively. – TLP Aug 08 '22 at 08:32

2 Answers2

4

To process files in subfolders as well, and (I presume) in sub-sub-folders, etc, that list of all "entries" (glob) need be split into files and folders. Edit the files and repeat the process in subfolders. This is often done recursively but there are other ways. It's a little job to do.

And there are libraries for recursive traversal and processing, of course. For example the core File::Find (or File::Find::Rule), or Path::Iterator::Rule. But since you also need to edit each file in a simple manner let's look at a more general utility Path::Tiny, which has a few methods for editing files in-place, as well.

If you insist on a command-line program ("one-liner")

perl -MPath::Tiny -we"
    path(qq(.))->visit( sub { 
        my ($entry, $state) = @_; 
        return if not -T;
        path($entry)->edit_lines( sub { s/.../.../g } )
    }, 
    { recurse => 1 }
)"

Here the visit method executes the sub { } callback on each entry under the given folder, and goes on recursively (with that option). We skip entries which aren't ASCII or UTF-8 files, by -T filetest.

Inside the callback, edit_lines processes each line of the file as specified in its sub; in this case, run the regex from the question. Once it's done with the whole file it replaces the original with the edited version. See docs.

zdim
  • 64,580
  • 5
  • 52
  • 81
  • `-wE` switches should probably be `-e`, or possibly `-we`. Not using any extended features in this code. And warnings are probably going to be spam for a bulk command. – TLP Aug 08 '22 at 09:07
  • 1
    @TLP Quite correct, thank you. (There's almost always some print so it's easy to forget...). Warnings I can't do without (the fingers reject) -- they can turn them off if they want. I'll comment though, good call – zdim Aug 08 '22 at 09:09
  • Sorry for the extremely late response. I learned from this response and modified it slightly to fit my needs. it is perfect. thank you so much @zdim! – LG Zana Aug 10 '22 at 10:30
  • 1
    @LGZana Great that it helps :) Let me know if there are questions – zdim Aug 10 '22 at 16:53
1

For this, I think it could be only done by perl commands, not in batch commands.

You can check here for more specific solutions

Phillip
  • 170
  • 4