Исходный файл C трудно анализировать, как и другие файлы со структурированными данными. Лучше использовать парсер, который знает о синтаксисе языка, чем пытаться справиться с ним самостоятельно.
Предположим, у вас установлены Exuberant Ctags какectags
:
find top-dir -type f -name '*.[ch]' -exec ectags -x --c-kinds=f {} ';' >table
Это найдет все файлы .c
и .h
в или под top-dir
и создаст файл table
. Содержимое table
будет выглядеть примерно так (, где top-dir
будет .
в этом примере )
.
GetTimeSeed function 373./src/bayes.c void GetTimeSeed (void)
InitializeMrBayes function 443./src/bayes.c int InitializeMrBayes (void)
PrintHeader function 821./src/bayes.c void PrintHeader (void)
ReinitializeMrBayes function 838./src/bayes.c int ReinitializeMrBayes (void)
main function 101./src/bayes.c int main (int argc, char *argv[])
readline_completion function 359./src/bayes.c char **readline_completion (const char *text, int start, int stop)
(и др.)
Этот выходной формат должен быть легко проанализирован, например, с помощью. awk
, чтобы получить именно тот формат, который вам нужен.
Как насчет
mapfile -t list < list.txt
i=0
for f in *.gf; do
echo mv "$f" "${list[i++]}_$f"
done
Удалите echo
, как только убедитесь, что он работает правильно.
POSIX -совместимое решение будет:
#!/usr/bin/env sh
i=0
for f in *.gf
do
echo mv "$f" "$(tail -n+$i list.txt | head -1)"_"$f"
i=$((i+1))
done
Протестировано с bash, dash, mksh и yash.
С синтаксисом POSIX sh
:
#! /bin/sh -
for f in *.gf; do
IFS= read -r line <&3 || break
mv -i -- "$f" "${line}_$f"
done 3< list.txt
Подстановка (здесь*.gf
)сортирует список файлов лексически (в соответствии с порядком сортировки локали в современных и POSIX-совместимых оболочках ).
Утилита paste(1)
(позволяет избежать медленных циклов оболочки и в целом проще):
# example list of files:
ls > files
paste -d_ list files
Если вам нужен mv
, то все немного сложнее:
paste -d_ list files | paste files - | xargs -n2 echo mv
Снимите echo
, когда будете готовы к работе.
Поскольку мы не используем ничего, кроме
Все это должно быть POSIX-совместимым,sh
-совместимым и, следовательно, чрезвычайно переносимым.
Но больше всего мне нравится то, как легко можно собирать на лету, в интерактивном режиме, по частям.
Использование GNU Parallel:
parallel mv {1} {2}_{1} ::::+ filenames list.txt
или:
parallel mv {1} {2}_{1} ::: * ::::+ list.txt