Какая хорошая команда для перемещения каталога, содержащего относительные символические ссылки на файлы, за пределы каталога?

Вы можете попробовать записать на C:

#include 
#include 
#include 
int main(){
  char buf[BUFSIZ];
  int nread;
  size_t nfound=0;
  while((nread=read(0, buf, BUFSIZ))>0){
    char const* p;
    for(p=buf; p=memchr(p,'\n',nread-(p-buf)); nfound++,p++) {;}
  }
  if(nread<0) { perror("Error"); return 1; }
  printf("%lu\n", nfound);
  return 0;
}

Сохранить, например, wcl.c , скомпилировать, например, с помощью gcc wcl.c -O2 -o wcl и запустить с

Это обнаруживает символы новой строки, разбросанные в файле размером 1 ГБ в моей системе примерно за 370 мс (повторные прогоны). (Увеличение размера буфера немного увеличивает время, чего и следовало ожидать - BUFSIZ должен быть близок к оптимальному). Это очень похоже на ~ 380 мс Я получаю от wc -l .

Mmaping дает мне лучшее время примерно 280 мс , но, конечно, имеет ограничение, заключающееся в том, что он ограничен реальными файлами (без FIFOS, без ввода терминала и т. Д.):

#include 
#include 
#include 
#include 
#include 
#include 
int main(){
  struct stat sbuf;
  if(fstat(0, &sbuf)<0){ perror("Can't stat stdin"); return 1; }

  char* buf = mmap(NULL, sbuf.st_size, PROT_READ, MAP_PRIVATE, 0/*stdin*/, 0/*offset*/);
  if(buf == MAP_FAILED){ perror("Mmap error"); return 1; } 

  size_t nread = sbuf.st_size, nfound=0;
  char const* p;
  for(p=buf; p=memchr(p,'\n',nread-(p-buf)); nfound++,p++) {;}

  printf("%lu\n", nfound);
  return 0;
}

Я создал свой тестовый файл с:

 $ dd if=/dev/zero of=file bs=1M count=1042 

и добавлены некоторые тестовые символы новой строки с:

 $ echo >> 1GB 

и шестнадцатеричный редактор.

1
01.12.2018, 11:10
2 ответа

Вот довольно деструктивный метод :заменить относительные ссылки абсолютными ссылками:

cd foo
for f in *; do
    if [[ -h $f ]]    # True if file is a symbolic link.
    then
        abs=$(readlink -f "$f") && rm "$f" && ln -s "$abs" "$f"
    fi
done
0
27.01.2020, 23:42

Наконец-то я написал решение и разместил его на Github:

https://github.com/minTaqa/mvrel

В настоящее время он не так гибок, как «mv», поскольку разрешены только два аргумента, а второй аргумент должен быть каталогом. Тем не менее, я нашел его полезным для перемещения чего-то, что имеет много относительных символических ссылок. Я хотел убедиться, что он может работать с пробелами, символами новой строки и прочей ерундой в именах файлов, так что это также был шанс для меня узнать о Bats, совместимом с TAP -фреймворке для тестирования, написанном на Bash, куда я поместил некоторые модули. тесты, чтобы убедиться, что все работает.

Сам скрипт тоже написан на Bash. Я думал, что это будет самый простой и переносимый язык для этой задачи, но в итоге мне пришлось обойти такие вещи, как тот факт, что подстановка команд удаляет завершающие символы новой строки(проблема, если у вас есть имена файлов с завершающими символами новой строки, что в основном теоретические, но все же раздражающие ). Затем идут find... -print0и IFS= read -rd '', а также множество кавычек и " --" аргументов --, которые не нужны в скриптовом языке немного более низкого -уровня, таком как Perl. Я также не стал бы выполнять манипуляции со строками путем раскрытия параметров в Perl. В любом случае, вы можете переписать его на Perl или даже на C, если хотите; как бы то ни было, в Bash он достаточно короткий.

1
27.01.2020, 23:42

Теги

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