2016-08-07 2 views
-2

Я пишу ls в Perl, ища строки, содержащие какие-либо символы, за которыми следует «.mp4.mp3» в конце строки. Я хочу удалить «.mp4» из середины строки. Вот моя команда:Perl regex non-greedy matching

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

Я использую нежадное согласование поэтому регулярное выражение будет прекратить потреблять линию, когда он работает в».mp4.mp3" . Я ожидал бы, что это будет работать только на линиях, которые заканчиваются на «.mp4.mp3», но он работает на строках без «.mp4» в них вообще.

Ввод: foo. bar.mp4.mp3

Ожидаемый результат: foo. bar.mp3

+0

Есть ли какой-либо r Вы не просто заменяете '.mp4.mp3'' .mp3'? – Laurel

+2

показать пример ввода и ожидаемого и фактического вывода – ysth

+0

, вы всегда должны включать предупреждения даже в oneliners. это не настоящая проблема здесь, но использование \ 1 вместо $ 1 с правой стороны замены является ошибкой. – ysth

ответ

3

Если под 'работает на линиях без».mp4" в них на всех' вы хотите, чтобы вы только распечатывали имена файлов, которые заменяли изменения, вам не нужно использовать -p и явно печатать те, которые вы хотите:

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

Я пытался в конечном итоге передать это в xargs -n2 mv, как я обычно делаю с sed (но sed не поддерживает не жадные, что мне действительно не нужно), но я вижу, что -p печатает каждую строку, в отличие от sed p, который печатает строки, где происходит замена. Я вижу, что perl может работать с файлами на месте с -i, но как я могу использовать это здесь? – crazyfox

+0

Неужели мой ответ не работает для вас? Вы также можете сделать редактирование на месте, но это не помогает, если вы хотите использовать xargs. – ysth

+0

Подождите, вы пытаетесь напечатать как старые, так и новые имена, так что mv переименовывает их? то вы хотите 'print if s/^ ((. *) \. mp4 \ .mp3) $/$ 1 \ n $ 2.mp3 /'. или еще лучше, просто используйте команду rename вместо perl. – ysth

1

Не overthink это :)

s/\.mp4\.mp3$/.mp3/ 

Переименование файлов в Perl:

ls | perl -lne '($newname = $_) =~ s/\.mp4\.mp3$/.mp3/; rename($_, $newname)'