Добавить строки списка в качестве префиксов в именах файлов

Исходный файл 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, чтобы получить именно тот формат, который вам нужен.

6
11.02.2020, 14:02
5 ответов

Как насчет

mapfile -t list < list.txt

i=0
for f in *.gf; do 
  echo mv "$f" "${list[i++]}_$f"
done

Удалите echo, как только убедитесь, что он работает правильно.

5
28.04.2021, 23:23

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.

0
28.04.2021, 23:23

С синтаксисом 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-совместимых оболочках ).

5
28.04.2021, 23:23

Утилита 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-совместимым и, следовательно, чрезвычайно переносимым.

Но больше всего мне нравится то, как легко можно собирать на лету, в интерактивном режиме, по частям.

0
28.04.2021, 23:23

Использование GNU Parallel:

parallel mv {1} {2}_{1} ::::+ filenames list.txt

или:

parallel mv {1} {2}_{1} ::: * ::::+ list.txt
0
28.04.2021, 23:23

Теги

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