Я повинен перейменувати набір файлів, використовуючи rename
команду (з регулярним виразом). Після деяких спроб я не в змозі знайти вираз, який отримає очікуваний результат.
У мене такий шаблон файлу:
prefix_ some_name _other.txt
Усі файли починаються з prefix_
рядка " " і закінчуються символом " _other.txt
", а частина some_name може складатися з декількох (буквено-цифрових) слів, розділених підкресленнями. Отже, можливо:
prefix_one_name_other.txt
prefix_this_is_my_name_1_this1_other.txt
Мені потрібно перейменувати такі назви файлів:
other_one-name_ datetime other_this-is-my-name-1-this1_ datetime
Іншими словами:
- Потрібно видалити "
prefix
" (залишаючи підкреслення) - "
other
" маркер переходить до початку імені файлу - У some_name перетворіть підкреслення (_) у тире (-)
- Підкреслення в кінці назви файла (після some_name ) має залишатися
- Потрібно видалити
.txt
розширення, замінене датою .
Що я спробував:
rename 's/fw_([a-z]+)_(\d)_(\w+\d)_(\w+)\.txt/$4_$1-$2-$3_'$datahora'/' *.txt
$datahora
має DateTime значення (перевірено). Це працює, як очікувалося
prefix_name_1_gnt1_other.txt
але не з
prefix_other_name_2_gnt2_other.txt
Де я помилився? Як ще я могла це досягти?
Я повісив свою думку, оскільки поки що я не в змозі знайти регулярний вираз, який працює для всіх імен файлів, які у мене є. Я знаю, що перший елемент рядка - це завжди prefix
частина, а останній елемент - це other.txt
частина рядка. Так можна розділити рядок на масив і отримати елементи, які мені потрібні для створення нового імені. Насправді щось подібне.
datahora="20140718-080000"
arrfiles=( *.txt )
for curfile in ${arrfiles[*]}
do
arrparts=( ${curfile//_/ } )
numitems=${#arrparts[*]}
newname=""
for (( c=1; c<numitems-1; c++ ))
do
newname+="${arrparts[c]}-"
done
newname=${newname%-}
arrparts[numitems-1]=${arrparts[numitems-1]/.txt/}
newname="${arrparts[numitems-1]}_${newname}_$datahora"
echo "$curfile pasa a $newname"
mv ${curfile} ${newname}
done
Після цього я зробив ще одну спробу запропонувати @peterph пропозицію, і, нарешті, зробив кілька перейменувань комбінацій регулярних виразів. Щось так подумайте:
rename 's/_/-/g' *.txt
rename 's/^fw-(.*)-([^-]*)(\.txt)/$2.$1$3/' *.txt
rename 's/(\w+)\.(.*)(\.txt)/$1_$2_'$datahora'/' *.txt
Я не впевнений, що найкращий підхід. На мій погляд, варіант регулярного виведення здається більш елегантним, але для виконання роботи мені потрібні три операції з перейменуванням (доступ три рази на диск), тоді як array
варіант записується лише один раз на диск.
¿Що ви думаєте про ці два рішення? ...
Знову дякую.