I'm trying
perl -pe 's;\A(?!syntax:);syntax: glob\n\n;' .hgignore
On a file with these contents:
dist
node_modules
.vscode
The output I expect is:
syntax: glob
dist
node_modules
.vscode
With the caveat that I can run it repeatedly and it won't keep pre-pending.
I'm \A(?!syntax:)
to anchor the regex to the start of the file and then (?!
to say "not followed by". Looks like \A
is matching the start of the line, not start of file.
How can I match only the very start of the file?
CodePudding user response:
With the -p
switch the file is read line by line, to start with. So the code never sees the whole file, only one line at a time.
To "slurp" the whole file into $_
do perl -0777 -pe'...' file
. That -0777
unsets the input record separator, so the "line" read by -p
is really the whole file. See it in perlrun
Then the regex will run on the multiline string with the whole file.
With a multiline string one often needs the /m
modifier, so that ^
and $
match beginning and end of lines inside the string, while we have \A
to match the beginning of the whole string. One also often needs the /s
modifier, so that .
matches a newline as well.
However, it seems that for your purpose those aren't needed. Then, without the /m
modifier the ^
anchor matches the beginning of the string, just like \A
. But I do find \A
still better as it expresses the intent clearly.
CodePudding user response:
The problem you are having is stemming from the fact that -p implies -n, which evaluates the program for each line of the file.
Your problem can be solved by only attempting the substitution on the first line of the file.
perl -pe's{^(?!syntax:)}{syntax: glob\n\n} if $. == 1' .hgignore
Alternatively, you could tell Perl the whole file is one line with -0777
or the newer -g
.
perl -0777pe's{^(?!syntax:)}{syntax: glob\n\n}' .hgignore