1

I have a text file named "data" with the content:

a
b
c
abc

I'd like to find all "abc" (doesn't need to be on the same line) and replace the leading "a" to "A". Here "b" can be any character (one or more) but not 'c'.

(This is a simplification of my actual use case.)

I thought this perl command would do

perl -pi.bak -e 's/a([^c]+?)c/A\1c/mg' data

With this 'data' was changed to:

a
b
c
Abc

I was expecting:

A
b
c
Abc

I'm not sure why perl missed the first occurrence (on line 1-3).

Let me know if you spot anything wrong with my perl command or you know a working alternative. Much appreciated.

2
  • You need perl -0777pe 's/a([^c]+)c/A$1c/g' or perl -0pe 's/a([^c]+)c/A$1c/g' Commented Jul 6, 2021 at 20:19
  • (You didn't need to delete the other question. Even duplicate questions can help people, since they might find the closed question in a search, and that will lead them to the answer.) Commented Jul 7, 2021 at 22:14

1 Answer 1

3

You're reading a line at a time, applying the code to that one line. It can't possibly match across multiple lines. The simple solution is to tell perl to treat the entire file as one line using -0777.

perl -i.bak -0777pe's/a([^c]+c)/A$1/g' data
  • Replaced the incorrect \1 with $1.
  • Removed the useless /m. It only affects ^ and $, but you don't use those.
  • Removed the useless non-greedy modifier.
  • Moved the c into the capture to avoid repeating it.
Sign up to request clarification or add additional context in comments.

1 Comment

For a more flexible solution might consider using \U$1\E$2 and capture the first match.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.