crazyfox crazyfox - 1 year ago 80
Perl Question

Perl regex non-greedy matching

I am piping ls into perl looking for lines that contain some any characters followed by ".mp4.mp3" at the end of the line. I want to remove the ".mp4" from the middle of the line. Here is my command:

ls | perl -pe 's|(.+?)\.mp4\.mp3$|\1\.mp3|'

I am using non-greedy matching so the regex will stop consuming the line when it runs into ".mp4.mp3". I would expect this to only operate on lines that end in ".mp4.mp3", but it is operating on lines without ".mp4" in them at all.

input: foo . bar.mp4.mp3

expected output: foo . bar.mp3

Answer Source

If by 'operating on lines without ".mp4" in them at all' you mean you only want to print out filenames that the substitution changes, you need to not use -p and explicitly print the ones you want:

ls | perl -wne'print if s/\.mp4\.mp3$/.mp3/'