Вы можете использовать переименование Perl, если оно доступно. Под переименованием Perl я подразумеваю переименование prename или файла -, а не rename.ul, который может быть тем, что rename
указывает на вашу систему, и который определенно приведет к ошибке, если вы попытаетесь использовать его с аргументами кода, которые у меня есть. предлагается ниже...
В моей системе (Ubuntu 17.10 -Я установил пакет rename
для переименования Perl):
$ readlink -e $(type -P rename)
/usr/bin/file-rename
Это единственная среда, в которой я тестировал этот ответ!
Если у вас есть только два уровня каталога, как в вашем примере, вы можете запустить из каталога lokesh
что-то вроде этого:
rename -n 's|/|/x_|' */*.c
Всегда запускайте сначала с флагом -n
, который показывает, какое изменение будет предпринято, если вы запустите тот же код без -n
. Если вы видите правильный результат, удалите -n
.
Если у вас сложная структура каталогов, вы можете использовать рекурсивную подстановку, если она доступна. В Баше:
shopt -s globstar
Тогда попробуйтеrename
:
rename -n 's|(.*)/|$1/x_|'./**/*.c
Это фиксирует все до последнего элемента пути (.*)/
и воспроизводит его с обратной ссылкой $1
.
В противном случае (, если вы не можете использовать рекурсивную подстановку ), используйтеfind
:
find. -type f -name "*.c" -exec rename -n 's|(.*)/|$1/x_|' {} +
Хотя это будет медленнее, если файлы находятся во многих каталогах,вы также можете использовать -execdir
, который допускает более простое регулярное выражение (Я обнаружил заметную разницу в скорости между-exec
(менее секунды )и-execdir
(3 -4 секунды )с ~1113 .c
файлов в ~175 каталогах):
find. -type f -name "*.c" -execdir rename -n 's|/|/x_|' {} +
-n
приводит к запутанным -выглядящим результатам с -execdir
, но если базовые имена выглядят правильно, все в порядке.
Однако, благодаря комментарию Кусалананды , я понимаю, что это зависит от наличия GNU find
, где все аргументы -execdir
начинаются с ./
, а не версии OpenBSD, где они не. Если имя файла вообще не имеет префикса пути, я думаю, вы можете использовать эту версию:
find. -type f -name "*.c" -execdir rename -n -- 's|^|x_|' {} +
но я не могу это проверить, так как у меня нет OpenBSD find
.
Тем не менее,Элиа Каган очень помог придумал гораздо лучшее регулярное выражение , которое работает независимо от используемой реализации find
и от того, используете ли вы -exec
или -execdir
, а также работает с рекурсивной подстановкой:
rename -n 's|[^/]+$|x_$&|'
Это соответствует как минимум 1 символу (s ), которые не являются /
в конце($
)пути, а затем воспроизводит все совпадение($&
)после добавленного x_
. Эта команда должна работать везде, find
и переименование Perl доступно:
find. -type f -name "*.c" -exec rename -n 's|[^/]+$|x_$&|' {} +
Типичный подход к этому — case
утверждение:
case $id in
(s001) do something
;;
(s002) do something else
do something additional
;;
(s003) do something else entirely
;;
(*) do something unexpected
;;
esac
Здесь нужно немного усилить синтаксис:
(*)
— это -все, если вы хотите запустить некоторые команды, когда ни одна из перечисленных опций не подходит. ;;
; есть и другие варианты окончания строф, менее распространенные. Я также предпочитаю помещать ;;
в отдельную строку, чтобы было легче понять, правильно ли я закончил строфы. Оператор case довольно быстрый, как сказал Шаллер выше. В противном случае, если вы предпочитаете условные операторы, вы можете написать что-то вроде:
if [[ -n "${id}" ]]; then
if [[ "${id}" == "s001" ]]; then
echo "do something"
elif [[ "${id}" == "s002" ]]; then
echo "do something else"
fi
fi
Обратите внимание, :тест -n предназначен для проверки того, что id установлен, чтобы при сравнении не было ошибок. Это в оболочке, условной, чтобы избежать переоценки.