Мне нужна помощь с регулярными выражениями. Областью этого является изменение имен файлов. Вот образец.
Super subject - Subject - Subsubject - Extra History - #number--hash.mp4
Как видно из следующих двух примеров, суперсубъект присутствует не всегда. Я хотел бы переместить #number после темы и удалить хэш в конце.
Мне нужна команда или скрипт bash, который это сделает.
Africa - Zulu Empire - Diamonds in South Africa - Extra History - #3--JG-5otw0O8.mp4
Simón Bolívar - Defeat is Not Surrender - Extra History - #4-Ie0IoiQQFKA.mp4
Я ищу вывод:
Africa - Zulu Empire 3 - Diamonds in South Africa - Extra History.mp4
Simón Bolívar 4 - Defeat is Not Surrender - Extra History.mp4
Я задаю этот вопрос таким образом, потому что я знаю, что регулярное выражение очень специфично, и я не изучал регулярное выражение. Если есть специальный инструмент, с помощью которого я могу решить эту проблему самостоятельно, дайте мне знать. Этот инструмент должен быть простым в использовании, пожалуйста.
Я не знаю регулярного выражения и у меня нет времени его изучать. Это занимает много времени, я учусь в школе, и я не знаю, хочу ли я в конце концов изучать регулярное выражение.
Подходит ли вам Perl-скрипт?
Вы имеете в виду что-то вроде этого?
sed 's/\([^-]*\) - \([^-]*\)\([^#]*\) - #\([0-9]*\)[^.]*\(.*\)$/\1 \4 - \2\3\5/' testdata.txt
testdata.txt
Africa - Zulu Empire - Diamonds in South Africa - Extra History - #3--JG-5otw0O8.mp4
Simón Bolívar - Defeat is Not Surrender - Extra History - #4-Ie0IoiQQFKA.mp4
выход
Africa 3 - Zulu Empire - Diamonds in South Africa - Extra History.mp4
Simón Bolívar 4 - Defeat is Not Surrender - Extra History.mp4
объяснение
sed 's/ # use sed substitution
\([^-]*\) # store all characters unequal - in arg1 (\2)
- # ignore separator
\([^-]*\) # store all characters unequal - in arg2 (\2)
\([^#]*\) # store all characters unequal # in arg1 (\3)
- # # ignore separator
\([0-9]*\) # store number in arg4 (\4)
[^.]* # ignore all chars unequal .
\(.*\) # store suffix in arg5 (\5)
/\1 \4 - \2\3\5/' # create output
Скрипт для переименования файлов в локальном каталоге
#!/bin/bash
for file in *.mp4; do
newname=$(sed 's/\([^-]*\) - \([^-]*\)\([^#]*\) - #\([0-9]*\)[^.]*\(.*\)$/\1 \4 - \2\3\5/' <<<"$file")
mv "$file" "$newname"
done
это почти все, но для Симона Боливара — Поражение — это не сдача — Дополнительная история — #4-Ie0IoiQQFKA.mp4 Я бы хотел, чтобы это был Симон Боливар 4 — Поражение — это не сдача — Дополнительная история.mp4
конечно - я расширил свое решение ;-)
Если для вас есть однострочный вариант Perl, вы можете сделать:
Внутри каталога, которому принадлежат файлы
perl -e '@l=glob("*.mp4");for(@l){$old=$_;@e=split(/ - /,$_);($n)=$e[-1]=~/(\d+)/;$_=($e[-5]?"$e[-5] - ":"")."$e[-4] $n - $e[-3] - $e[-2].mp4";rename$old,$_}'
Объяснение:
perl -e ' # invoke perl
@l=glob("*.mp4"); # search all mp4 in current directory
for(@l){ # for each file found
$old=$_; # save old name
@e=split(/ - /,$_); # explode filename on ' - '
($n)=$e[-1]=~/(\d+)/; # extract the number from last element
$_= # new name
($e[-5]?"$e[-5] - ":""). # first element if exists
"$e[-4] $n - $e[-3] - $e[-2].mp4"; # all other element except the last
rename$old,$_ # rename the file
}' # end script
Я предлагаю вам сохранить исходный каталог перед запуском этого
В действии с вашими двумя примерами:
~/devel/tmp$ll
total 8
drwxr-xr-x 2 olivier olivier 4096 mai 28 17:13 ./
drwxr-xr-x 6 olivier olivier 4096 nov. 19 2018 ../
~/devel/tmp$touch "Africa - Zulu Empire - Diamonds in South Africa - Extra History - #3--JG-5otw0O8.mp4"
~/devel/tmp$touch "Simón Bolívar - Defeat is Not Surrender - Extra History - #4-Ie0IoiQQFKA.mp4"
~/devel/tmp$ll
total 8
drwxr-xr-x 2 olivier olivier 4096 mai 28 17:13 ./
drwxr-xr-x 6 olivier olivier 4096 nov. 19 2018 ../
-rw-r--r-- 1 olivier olivier 0 mai 28 17:13 Africa - Zulu Empire - Diamonds in South Africa - Extra History - #3--JG-5otw0O8.mp4
-rw-r--r-- 1 olivier olivier 0 mai 28 17:13 Simón Bolívar - Defeat is Not Surrender - Extra History - #4-Ie0IoiQQFKA.mp4
~/devel/tmp$perl -e '@l=glob("*.mp4");for(@l){$old=$_;@e=split(/ - /,$_);($n)=$e[-1]=~/(\d+)/;$_=($e[-5]?"$e[-5] - ":"")."$e[-4] $n - $e[-3] - $e[-2].mp4";rename$old,$_}'
~/devel/tmp$ll
total 8
drwxr-xr-x 2 olivier olivier 4096 mai 28 17:14 ./
drwxr-xr-x 6 olivier olivier 4096 nov. 19 2018 ../
-rw-r--r-- 1 olivier olivier 0 mai 28 17:13 Africa - Zulu Empire 3 - Diamonds in South Africa - Extra History.mp4
-rw-r--r-- 1 olivier olivier 0 mai 28 17:13 Simón Bolívar 4 - Defeat is Not Surrender - Extra History.mp4
это легко сделать с помощью какого-нибудь инструмента, такого как awk/sed, но SO так не работает. с какой проблемой вы сталкиваетесь во время написание собственных кодов?