Ошибка переименования подходящих файлов с помощью perl one liner - PullRequest
2 голосов
/ 04 июля 2019

Я хочу переименовать все файлы, которые соответствуют шаблону. Этот тип лайнеров обычно работает для меня, но я получаю какую-то ошибку.

Вид имен файлов, которые у меня есть: PMSNpoda5718_1p2g_out_fst.txt SCSNpoda5718_1p2g_out_fst.txt

Имена файлов, которые я хочу: PM-SN_poda5718_1p2g_out_fst.txt SC-SN_poda5718_1p2g_out_fst.txt

Моя первая попытка была:

ls *fst.txt | perl -ne '/^([A-Z][A-Z])([A-Z][A-Z])(poda.*?$)/; system("mv $_ $1-$2_$3")'

Но это не сработало.

Наконец я придумал строку, которая печатает именно то, что я хочу

ls *fst.txt | perl -lne '/([a-zA-Z]{2})([a-zA-Z]{2})(poda.*?$)/; print "mv $_ $1-$2_$3"'

печать:

mv PMSNpoda5718_1p2g_out_fst.txt PM-SN_poda5718_1p2g_out_fst.txt
mv SCSNpoda5718_1p2g_out_fst.txt SC-SN_poda5718_1p2g_out_fst.txt

Но когда я использую его для переименования файлов:

ls *fst.txt | perl -lne '/([a-zA-Z]{2})([a-zA-Z]{2})(poda.*?$)/; system("mv $_ $1-$2_$3")'

Я получаю

sh: $'32mPMSNpoda5718_1p2g_out_fst.txt\E[0m': command not found
mv: missing destination file operand after ''$'\033''[01'
Try 'mv --help' for more information.
sh: $'32mSCSNpoda5718_1p2g_out_fst.txt\E[0m': command not found
mv: missing destination file operand after ''$'\033''[01'
Try 'mv --help' for more information.

Снова, но с добавлением эха

ls *fst.txt | perl -lne '/([a-zA-Z]{2})([a-zA-Z]{2})(poda.*?$)/; system("echo mv $_ $1-$2_$3")'

Я получаю

mv
h: $'32mPMSNpoda5718_1p2g_out_fst.txt\E[0m': command not found
mv
h: $'32mSCSNpoda5718_1p2g_out_fst.txt\E[0m': command not found

Может кто-нибудь указать мне, в чем заключается ошибка, чтобы я мог понять, что я делаю неправильно?

Спасибо!

1 Ответ

4 голосов
/ 04 июля 2019

Нет смысла запускать переименование через оболочку.

ls -1 *fst.txt | perl -MFile::Copy=move -wlnE'
    $new = s/([a-zA-Z]{2})([a-zA-Z]{2})/$1-$2_/r; move $_, $new'

Обратите внимание на параметр -1 на ls, так что вы получите одно имя файла на строку.

32m и [0m - это экранирования ANSI, которые могут задавать цвета (и другие свойства) для терминала, часто используемые для конфигурации оболочки (например, для запроса).Возможно, ваш ls выпускает их, а mv ужасно запутывается с ними?Еще один пример того, почему лучше не проходить через оболочку, если в этом нет необходимости, конечно.

В некоторых оболочках существующий псевдоним, посредством которого команда фактически запускается с различными параметрами (именно поэтому вывод ls «одевается» с этими кодами), может быть подавлен путем добавления команды к обратной косой черте.\ls.

Другой вариант - максимально уменьшить зависимость от системы, а также создать список файлов в программе

perl -MFile::Copy=move -wE'
    for (glob "*fst.txt") { 
        $new = s/([a-zA-Z]{2})([a-zA-Z]{2})/$1-$2_/r;
        move $_, $new or warn "Cant rename $_ to $new: $!" }'

, где теперь ответственность за создание правильного списка файлов glob.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...