Команда rename
вам нужна:
Если вы используете rename
из util-linux
:
переименовать . _1. *.orig && переименовать .orig '' *.orig
Первый заменит первое вхождение .
с _1.
для всех файлов, оканчивающихся на .orig
. Второй удалит .orig
из имен файлов.
Если вы используете perl-rename (по умолчанию в системах на основе Debian), все проще, поскольку он использует Perl-совместимые регулярные выражения, поэтому все можно сделать за один шаг:
rename 's/(\..* )\.orig/_1$1/' *orig
Поскольку эта версия использует регулярное выражение, оно будет соответствовать первому .
(\.
, .
необходимо экранировать, поскольку ti означает «любой символ», если он не экранирован), затем все (.*
) до .ориг
. Так как первый шаблон находится внутри круглых скобок, он "захвачен" и впоследствии может упоминаться как $1
. Следовательно, замена заменит все, что ранее совпало с _1
и захваченным шаблоном (первое расширение), и одновременно удалит .orig
.
Команды с find
можно комбинировать следующим образом:
find /example -name '*.orig' -exec rename . _1. {} +
find /example -name '*.orig' -exec rename .orig '' {} +
Или:
find /example -name '*.orig' -exec rename 's/(\..*)\.orig/_1$1/'
Для этого даже не требуется find
.Если все ваши файлы находятся в одном каталоге, вы можете использовать приведенные выше команды напрямую или, чтобы сделать его рекурсивным (при условии, что вы используете bash):
shopt -s globstar ## make ** recurse into subdirectories
rename.ul . _1. **.orig && rename.ul .orig '' **.orig ## util-linux
rename 's/(\..*)\.orig/_1$1/' **orig ## perl rename
На самом деле, строго говоря, вам даже не нужно переименовать
. Вы можете делать все в оболочке (см. здесь для объяснения возможностей оболочки по работе со строками):
for file in **/*.orig; do
newname="${file%%.*}_1.${file#*.}"
mv "$file" "${newname/.orig/}"
done
Наконец, примечание о шаблонах ( -name
использует шаблон регулярное выражение). *.*.orig
— это синтаксис Windows для «всего, что заканчивается на .orig
». Эквивалент и то, что вы должны использовать с вашим find
, это *.orig
. Только *
соответствует чему угодно, использование *.*.orig
будет соответствовать только именам файлов с двумя расширениями, последнее из которых — .orig
.
Похоже, вам придется либо добавить каждый каталог, содержащий исполняемый файл, отдельно, либо связать все исполняемые файлы с одним и тем же каталогом.
Добавить все каталоги вручную.
Сначала соберите список соответствующих каталогов (я предполагаю, что вы используете Linux или, в любом случае, у вас есть инструменты GNU):
find / home / cs / Id -type f -executable -exec dirname {} + | sort -u
Вышеупомянутый код найдет все исполняемые файлы в / home / cs / Id
и распечатает имя каталога, в котором они находятся. sort -u
гарантирует, что каждый каталог будет напечатан только один раз.Я создал несколько тестовых каталогов, поэтому в своей системе я получаю:
$ find / home / terdon / Idl / -type f -executable -exec dirname {} + | sort -u
/ home / terdon / Idl / foo / bar / bag / ho
/ home / terdon / Idl / foo / bar / bag / ho / fa / fe / re {{1 }} / home / terdon / Idl / foo / bar / baz / foo / bar
/ home / terdon / Idl / foo / bar / baz / foo / bar / baz / foo / bar / baz {{1 }}
Теперь вам нужно преобразовать их в правильный формат для добавления в $ PATH
:
$ find / home / terdon / Idl / -type f -executable -exec dirname {} + | sort -u | tr '\ n' ':'
/ home / terdon / Idl / foo / bar / bag / ho: / home / terdon / Idl / foo / bar / bag / ho / fa / fe / re: / home / terdon / Idl / foo / bar / baz / foo / bar: / home / terdon / Idl / foo / bar / baz / foo / bar / baz / foo / bar / baz:
Копировать это (исключая последний :
) и добавьте его в свой PATH
:
PATH = "$ PATH: / home / terdon / Idl / foo / bar / bag / ho: / home / terdon / idl / foo / bar / bag / ho / fa / fe / re: / home / terdon / idl / foo / bar / baz / foo / bar: / home / terdon / idl / foo / bar / baz / foo / bar / baz / foo / bar / baz "
Найдите все исполняемые файлы и символически привяжите их к каталогу, уже находящемуся в вашем PATH .
find / home / terdon / Idl / -type f -executable -exec ln -s {} ~ / bin \;
В некоторых системах Linux (например, Ubuntu) Каталог ~ / bin
автоматически добавляется в ваш ПУТЬ
, если он существует. Если этого не происходит в вашей системе, добавьте это самостоятельно:
PATH = "$ PATH: / home / cs / bin"
Я думаю тогда нужно перечислить каталоги. Это автоматически сгенерирует для вас строку:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Copyright © 2016 Martin Ueding <dev@martin-ueding.de>
# Licensed under the MIT license
import argparse
import os
def main():
options = _parse_args()
additions = []
for base in options.base:
for dirpath, dirnames, filenames in os.walk(base):
additions.append(dirpath)
line = ':'.join(additions)
if options.short:
print(line)
else:
print('PATH=$PATH:'+line)
def _parse_args():
parser = argparse.ArgumentParser(description='')
parser.add_argument('base', nargs='+', help='Basepath')
parser.add_argument('--short', action='store_true')
options = parser.parse_args()
return options
if __name__ == '__main__':
main()
Сохраните этот фрагмент как / usr / bin / path-recurse
и примените chmod + x / usr / bin / path-recurse
.Затем вы можете использовать его в своем приглашении либо для создания строки с path-recurse / tmp / foobar…
, и он выдаст вам строку Bash:
PATH=$PATH:/tmp:/tmp/kde-muIusrrC:/tmp/vs0cOIg:/tmp/.esd-1000:/tmp/ssh-oGWOvuUnyqPF:/tmp/.Test-unix:/tmp/.font-unix:/tmp/.XIM-unix:/tmp/.ICE-unix:/tmp/.X11-unix
В качестве альтернативы вы можете использовать следующее в своем ] .bashrc
:
PATH=$PATH:$(path-recurve /tmp /foobar …)
Затем он будет динамически проходить по всем папкам при каждом источнике .bashrc
.
Думаю, я решил свою проблему. Все, что я сделал в моем файле .bashrc, я написал:
PATH = $ {PATH}: $ (find ~ / Idl -type d | tr '\ n' ':' | sed 's /: $ //')
Затем:> source .bashrc
Теперь я могу запускать все программы и сценарии в различных подкаталогах в моем основном каталоге Idl.
Спасибо всем за внимание.