2015-01-25 5 views

ответ

2

Есть два инструмента rename. Тот, который вы пытаетесь использовать, основан на Perl и как таковой использует регулярные выражения в стиле perl. Правила экранирования немного отличаются от правил sed; в частности, скобки для группировки не экранированы (скопированные скобки являются буквальными круглыми скобками). Используйте

rename 's/^([0-9]|[0-9][0-9])_//' * 

или, несколько более лаконично,

rename 's/^[0-9]{1,2}_//' * 

Этот rename является по умолчанию в дистрибутивах Debian на базе таких как Ubuntu.

Другие инструменты rename от util-linux, и это очень простой инструмент, который не работает с регулярными выражениями и не может справиться с этим конкретным требованием. Это значение по умолчанию, например, на основе Fedora, и, что еще хуже, они часто даже не упаковывают Perl-переименование. Вы можете найти Perl переименовать here на CPAN и поместить его в /usr/local/bin, если вы хотите, но в противном случае, ваш самый простой вариант, вероятно, петля оболочки с mv и sed:

for f in *; do 
    # set dest to the target file name 
    # Note: using sed's extended regex syntax (-r) because it is nice. 
    #  Much less escaping of metacharacters is needed. Note that 
    #  sed on FreeBSD and Mac OS X uses -E instead of -r, so there 
    #  you'd have to change that or use regular syntax, in which 
    #  the regex would have to be written as ^[0-9]\{1,2\}_ 
    dest="$(echo "$f" | sed -r 's/^[0-9]{1,2}_//')" 
    if [ "$f" = "$dest" ]; then 
     # $f did not match pattern; do nothing 
     true; 
    elif [ -e "$dest" ]; then 
     # avoid losing files. 
     echo "$dest already exists!" 
    else 
     mv "$f" "$dest" 
    fi 
done 

Вы можете поместить это в сценарий оболочки, говорят rename.sh:

#!/bin/sh 

transform="$1" 
shift 

for f in "[email protected]"; do 
    dest="$(echo "$f" | sed -r "$transform")" 
    if [ "$f" = "$dest" ]; then 
     ## do nothing 
     true; 
    elif [ -e "$dest" ]; then 
     echo "$dest already exists!" 
    else 
     mv "$f" "$dest" 
    fi 
done 

и вызвать rename.sh 's/^[0-9]{1,2}_//' *.

Одно предостережение остается: в

dest="$(echo "$f" | sed -r "$transform")" 

есть вероятность того, что "$f" может быть то, что echo рассматривает вариант командной строки, такие как -n или -e. Я не знаю способ решить эту проблему (если вы прочтете это и узнаете, пожалуйста, оставьте комментарий), но если вы находитесь в положении, когда привязка себя к bash не представляет проблемы, вы можете использовать здесь bash здесь вместо:

dest="$(sed -r "$transform" <<< "$f")" 

(и заменить #!/bin/sh хижину с #!/bin/bash). Однако такие файлы редки, так что, как и временные бомбы, это вряд ли будет ошибкой.

+0

он не работает; ( – EpiMan

+0

Одд, это работает для меня это 'rename' вы используете' prename' из Perl Похоже, вы пытаетесь использовать это, и мой ответ, а зависит.? это – Wintermute

+0

от Linux! Я уже был установлен на сервере!как я могу это проверить? – EpiMan

1
#!/bin/bash 
for f in * 
do 
    mv "$f" "${f#*_}" 
done 
+0

tnx alot, не могли бы вы объяснить мне, что означает «$ f» "$ {f # * _}"? что означает $ {f # * _}? – EpiMan

+0

Один из них - один аргумент 'mv', а другой - другой аргумент' mv'. http://tldp.org/LDP/abs/html/parameter-substitution.html –

Смежные вопросы