Инструмент для переименования файлов с некоторой логикой

Чтобы узнать, какие динамические библиотеки экспортируют какой символ в системе GNU, вы можете попробовать что-то вроде:

ldconfig -p |
  sed -n 's/.* => //p' |
  sort -u |
  xargs -d '\n' nm --defined-only -oDg |
  grep -w getpid

(в первом приближении; это можно улучшить, удалив дубликаты на уровне inode ).

Нечто подобное можно сделать со статическими библиотеками или любым ELF или другим объектом, поддерживаемым nm, хотя вам может потребоваться адаптировать флаги и способ сбора списка файлов, в которых вы хотите выполнить поиск.

Однако здесь NLMSG_DATAв верхнем регистре, скорее всего, является макросом препроцессора C.

$ grep -r NLMSG_DATA /usr/include
/usr/include/linux/netlink.h:#define NLMSG_DATA(nlh)  ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))

Для поиска определений в заголовках C вместо grepвы можете использовать некоторые инструменты индексации кода, такие как ctags, cscopeили gtags, и проиндексировать весь /usr/include.

Вы также можете получить процессор C pre -, чтобы расширить его:

printf '%s\n' '#include <linux/netlink.h>' 'please_describe[NLMSG_DATA(nlh)]' |
  gcc -P -E -x c - | sed '/please_describe/,$!d'
please_describe[((void*)(((char*)nlh) + ((0) + ((int) ( ((sizeof(struct nlmsghdr))+4U -1) & ~(4U -1) )))))]

Таким образом, он просто возвращает указатель, смещенный относительно входного указателя на основе размера struct nlmsghdr(, который можно определить с помощью компилятора C или символов отладки некоторого объекта, который использует этотstruct).

Обратите внимание, что заголовки нужны не для запуска программного обеспечения, а только для их сборки, они не будут установлены по умолчанию для всех библиотек, поэтому вам может потребоваться установить некоторые пакеты xxx-devили xxx-devel, чтобы добавить их.

Если у вас есть справочная страница для библиотечной функции (, здесь она не применима, так как это какой-то API ядра ), скорее всего, у вас также есть заголовочные файлы. Вы можете перейти от справочной страницы к пакету, а затем к заголовкам и библиотеке. Например, в Debian и производных для функции attr_setf:

$ man -w attr_setf
/usr/share/man/man3/attr_set.3.gz
$ dpkg -S /usr/share/man/man3/attr_set.3.gz
libattr1-dev:amd64: /usr/share/man/man3/attr_set.3.gz
$ dpkg -L libattr1-dev | grep /include/
/usr/include/attr
/usr/include/attr/attributes.h
/usr/include/attr/error_context.h
/usr/include/attr/libattr.h
/usr/include/attr/xattr.h

Для библиотек вы можете предположить, что пакет libattr1или использовать тот факт, что пакет -devбудет зависеть от пакета времени выполнения:

$ apt-cache show libattr1-dev | grep Depends
Depends: libc6-dev | libc-dev, libattr1 (= 1:2.4.47-2build1)
$ dpkg -L libattr1 | grep /lib/
/lib/x86_64-linux-gnu
/lib/x86_64-linux-gnu/libattr.so.1.1.0
/lib/x86_64-linux-gnu/libattr.so.1
$ nm -Dg /lib/x86_64-linux-gnu/libattr.so.1 | grep attr_setf
00000000000016e0 T attr_setf

Если у вас нет справочной страницы, но вы знаете, что она существует,вы можете посмотреть -, какой пакет доступен из:

$ apt-file search -x 'man.*/attr_set\.\d'
libattr1-dev: /usr/share/man/man3/attr_set.3.gz
ncurses-doc: /usr/share/man/man3/attr_set.3ncurses.gz
2
25.05.2020, 12:51
3 ответа

Если вы используете bash,тогда шаблон !(*high*)будет соответствовать всем именам в текущем каталоге, которые не содержат строку high, если установлена ​​опция оболочки extglob:

$ shopt -s extglob
$ ls
1      2      3      4-high
$ ls -d -- !(*high*)
1 2 3

Затем мы можем перебрать имена, соответствующие этому шаблону, переименовав каждое совпадающее имя:

shopt -s extglob nullglob

for name in !(*high*); do
    [[ ! -f $name ]] && continue

    mv -- "$name" "high-$name"
done

Здесь происходит то, что мы устанавливаем extglob, а такжеnullglob(заставляем шаблон подстановки исчезать, а не сохраняться, как -, если шаблон не соответствует )перед циклом. Вы также можете включить dotglob, если хотите также переименовывать скрытые имена.

Затем цикл пропускает любое имя, которое не относится к обычному файлу (это может быть имя каталога, например ), а затем вставляет строку high-перед именем с mv.

Параметр --в команде mvпозволяет избежать ошибочной интерпретации любых имен файлов, начинающихся с дефиса, как набора параметров.

Запуск на наборе тестовых файлов:

$ ls
1      2      3      4-high

Просто вставьте код сверху прямо в оболочку:

$ shopt -s extglob nullglob
$
$ for name in !(*high*); do
>     [[ ! -f $name ]] && continue
>
>     mv -- "$name" "high-$name"
> done
$ ls
4-high high-1 high-2 high-3

Вы также можете использовать утилиту Perl renameследующим образом:

shopt -s extglob
rename -v 'if (-f) { s/^/high-/ }' -- !(*high*)

Это переместит проверку -fцикла в первом варианте этого ответа на Perl, но по-прежнему будет использовать тот же шаблон подстановки имен файлов для выбора файлов для переименования. -fпереименование затрагивает только обычные файлы (без каталогов и т. д.)


Вариантом, который не зависит от расширенных шаблонов подстановки в оболочке, будет

rename -v 'if (-f && !/high/) { s/^/high-/ }' -- *

Это просто проверяет, содержит ли имя уже строку highвнутри вызова rename, и пропускает переименование файла, если оно происходит. Глоб *выбирает все файлы в текущем каталоге (, кроме скрытых ).

1
18.03.2021, 23:33

Если у вас есть GNU Parallel:

parallel mv {} '{= /high/ or $_="high$_" =}' ::: *
1
18.03.2021, 23:33

Сzsh:

autoload zmv # best in ~/.zshrc
zmv '^*high*' 'high-$f'

С корпусом -нечувствительное согласование:

zmv '^*(#i)high*' 'high-$f'
1
18.03.2021, 23:33

Теги

Похожие вопросы