ls
знает, посылает ли он вывод на терминал или нет.
Выполнение ls
в командной строке приведет к записи на ваш псевдотерминал. Перенаправление вывода ls
обычно не идет на псевдотерминал, а ls
будет форматировать вывод по-другому.
Если у вас есть доступ к perl-rename
(называется rename
в системах на основе Debian, включая Ubuntu, perl-rename
в Arch и prename
на других), вы можете сделать:
perl-rename -n 's/(\[.*?\])\s*(.*)/$2 - $1/' ./\[*
-n
: это заставляет perl-rename
печатать то, что он будет делать, фактически ничего не переименовывая. Запустите его таким образом и, если он работает так, как ожидалось, удалите -n
, чтобы он действительно переименовывался. s/from/to/
: заменит from
на to
. s/(\[.*?\])\s*(.*)/$2 - $1/'
: здесь from
— это все, что находится между первым [
и первый ]
(\[.*?\]
). Затем 0 или более пробельных символов (\s*
), а затем все остальное (.*
). Круглые скобки вокруг шаблонов будут захватывать их, позволяя нам использовать их как $1
и $2
соответственно в правой части подстановки. Итак, это поместит все после [ ]
($2
) перед скобками ($1
). ./\[*
запустить его для всех файлов и каталогов в текущем каталоге, имя которого начинается с [
. Вы не хотите -t
в вашей ситуации. Это скажет mv
попытаться переместить нужное имя в каталог с именем $f
.
Это расширится до чего-то вроде:
mv -t "[2015] Name of the album" "Name of the album - [2015]"
что, вероятно, вам нужно без -t
. Как таковой он рассматривает $f
как имя целевого каталога, в который следует переместить все остальные аргументы.
Ваше решение работает, если вы удалите параметр -t
, как объяснил Эрик.
Это альтернативное решение, использующее подстановку переменных вместо awk
для перемещения битов имени файла:
for name in '['*; do
tag="${name%% *}"
title="${name#* }"
mv "$name" "$title - $tag"
done
${name%% *}
удаляет все после первого пробела в $name
(, включая пробел )и ${name#* }
удаляет все до первого пробела (, включая пробел ).