Заставьте использование копий каталога найти

Это репозитории для исходных пакетов. Посмотрите sources.list страница справочника.

3
31.07.2012, 06:17
6 ответов

Это не задание для find, с тех пор нет никакой включенной рекурсии.

for x in */C/populate.sh; do
  mkdir -- "${x%%/*}$suffix"
  mkdir -- "${x%%/*}$suffix/C"
  cp -p -- "$x" "./${x%%/*}$suffix/C"
done

Удалите -p опция к cp если Вы не хотите сохранять время изменения файлов.

Генерировать случайный суффикс, BSD/Linux mktemp является столь портативным, как это добирается.

suffix=$(mktemp -u tmp_XXXXX)

Если Вы хотите что-то неопределенно случайно выглядящее и совместимый POSIX, это дает строку, которая изменяется каждую секунду и варьируется от местоположения до местоположения; Вы не можете действительно добиться большего успеха только с инструментами POSIX:

suffix=$({ hostname; pwd; date; } |
         cksum | uuencode -m /dev/stdin | awk 'NR==2 {print substr($0,3,5)}')

При помещении этого кода в make-файл не забудьте:

  • удвойте все $ знаки;
  • поместите весь код одной строки, с помощью ; вместо этого для разделения инструкций по оболочке (можно использовать backslash+newline+tab для помещения разрыва строки в make-файл, но та последовательность удалена для создания команды оболочки);
  • запустите отрывок оболочки с set -e, так, чтобы это прервалось, если существует какая-либо ошибка.
3
27.01.2020, 21:11
  • 1
    Привет Gilles, спасибо за указатели. Несколько вопросов. 1) Использование find кажется безопасным для меня, даже если не строго необходимый. Можно ли уточнить то, как метод работает? Делает Ваше соответствие метода все каталоги, даже каталоги как .foo? 2), Если Вы хотите некоторую строку make-файла (который является отрывком оболочки) прерываться на ошибке, лучший способ снабдить префиксом его set -e? –  Faheem Mitha 01.08.2012, 10:51
  • 2
    @FaheemMitha 1) * не соответствует .foo. В дереве компиляции это обычно - желаемое поведение, пропуская .svn и т.п. (хотя здесь требование, чтобы иметь путь C/populate.sh исключит их так или иначе). Добавить .[!.]*/C/populate.sh если у Вас есть каталоги, имя которых начинается с точки. 2) Запустите команду с set -e. Например. set -e; for x in … –  Gilles 'SO- stop being evil' 01.08.2012, 11:17
  • 3
    Привет, Gilles. Изучив Ваш пример еще немного, это главным образом делает то, что я хочу, но у меня есть еще некоторые вопросы. for x in */C/populate.sh соответствия x с чем-либо формы */C/populate.sh. Конструкция ${x%%/*} соответствует первой части строки, а именно, высокоуровневое имя каталога. Можно ли уточнить эти две части синтаксиса и/или обеспечить ли ссылки? Синтаксис как %% немного трудно к Google для.Спасибо. Я решил попытаться сохранить эти значения к массиву. См. unix.stackexchange.com/q/44554/4671 - я буду обновлять тот вопрос вскоре. –  Faheem Mitha 02.08.2012, 22:06
  • 4
    @FaheemMitha % в руководстве Вашей оболочки в разделе о расширении параметра. ${x%%/*} $x с самым долгим соответствием для шаблона /* удаленный в конце, т.е. это $x минус все после первого /. –  Gilles 'SO- stop being evil' 02.08.2012, 23:21
  • 5
    Спасибо, это очень полезно. Для записи в Справочнике Bash это соответствует биту, запускающемуся с ${parameter%%word}. Еще одна вещь: какова функция --? Я попробовал его без, например. mkdir -p "${x%%/*}$suffix/C", и это все еще работает. –  Faheem Mitha 03.08.2012, 00:14

Можно создать копию каждого высокоуровневого использования каталога

$ find . -maxdepth 1 -type d -exec mkdir {}".tmpvalue" \;

Можно затем выполнить итерации и скопировать .sh файл к каждому из этих каталогов.

1
27.01.2020, 21:11
  • 1
    К сожалению, это не вполне работает с тех пор find . -maxdepth 1 -type d на самом деле включает текущий каталог также, который мы не хотим здесь. Таким образом, это должно быть исключено так или иначе. –  Faheem Mitha 31.07.2012, 07:23
  • 2
    Хорошо, rnd=$(tr -cd a-z0-9 < /dev/urandom | head -c5); find . -mindepth 1 -maxdepth 1 -type d -exec mkdir {}".tmp_"$rnd \; работы. –  Faheem Mitha 31.07.2012, 07:32

Попробуйте что-то вроде этого:

#!/bin/sh
# Create a temporary partial clone of the current directory
tcopy=`mktemp -d /tmp/tmp_XXXXX`
tbase=`basename $tcopy`
find . -name populate.sh -print | cpio -pud "$tcopy"

# Randomize the clone
for d in "$tcopy"/*
do
    mv "$d" "$d.$tbase"
done

# Merge the clone back into the current tree
mv "$tcopy"/* .

Это зависит от a mv реализация, которая знает, как переместить целые каталоги через файловые системы. GNU mv может, но я не забываю работать над некоторыми старыми полями Unix, где та заключительная строка не работала бы. Вы могли использовать другого find | cpio передайте вместо этого в этом случае. mv более эффективно, если это работает.

1
27.01.2020, 21:11
  • 1
    Любая алфавитно-цифровая строка работала бы на временное имя. Так, это могло бы быть похожим libc.tmp_txw2e или что-то. Я хотел бы, чтобы случайная строка была похожа tmp_ сопровождаемый 5 символами, если это возможно. –  Faheem Mitha 31.07.2012, 05:16
  • 2
    Это не делает то, что я хочу. Я хочу, чтобы подкаталоги были созданы на том же уровне, как в моем примере. Это создает целую отдельную структуру каталогов. Если я неправильно понимаю, можно ли обеспечить сессию в качестве примера?Спасибо. –  Faheem Mitha 31.07.2012, 05:28
  • 3
    Переписал мой ответ для обращения к этим комментариям. Если это все еще не получает его, отредактируйте свой вопрос дать пару find . -print выводы, с прежде и после. –  Warren Young 31.07.2012, 05:49

Я не волновался бы слишком много о -print0 пока имена файлов хорошо формируются. Ниже пример, который должен сделать то, что Вы хотите:

rnd=$(tr -cd a-z0-9 < /dev/urandom | head -c5)
find . -maxdepth 1 -type d | while read dir; do
   mkdir -p ${dir}_${rnd}/C
   cp populate.sh ${dir}_${rnd}/C
done

Объяснение

  • tr -cd удаляет дополнение указанного шаблона, буквенно-цифровой индикатор в этом случае.
  • head -c5 берет первые пять символов и выходы.
  • while выполнения read команда для каждой строки это find обеспечивает.
  • read присваивает каталог от find кому: $dir.
1
27.01.2020, 21:11
  • 1
    Это не работает совершенно верно. Если я удаляю cp строка, затем только один каталог создается, и это не имеет имени dir перед ним, это - просто 5 символьных случайных строк. Так, я прихожу к заключению, что $dir не становится присвоенным правильно, и также цикличного выполнения не происходит правильно. Также первый аргумент в cp не работал бы - populate.sh, снижается на два уровня. Если Вы могли бы объяснить while read dir бит, который был бы полезен. –  Faheem Mitha 31.07.2012, 07:14
  • 2
    $dir потребности, которые будут защищены от других типов расширения, так для фиксации помещенные фигурные скобки вокруг этого: ${dir}. Я обновил пример. –  Thor 31.07.2012, 11:32
  • 3
    Используйте populate.sh это имеет смысл в Вашем случае. –  Thor 31.07.2012, 11:34

Если другие ищут, как скопировать найти результаты и создать промежуточные каталоги, можно использовать --родителей с GNU cp, rsync -R, pax -rw, или cpio -pd.

find . -type f -exec cp --parents -t /tmp {} +
  --parents creates intermediate directories in GNU cp
  -t specifies a target directory in GNU cp
find . -type f -print0|xargs -0I, rsync -R , /tmp
  -R is --relative
find . -type f|pax -rw /tmp
  -rw (read and write) copies files
  pax is required by POSIX but not LSB and not included by some Linux distributions
find . -type f|cpio -pdu /tmp
  -p (pass-through) copies paths from stdin to a specified directory
  -d creates intermediate directories
  -u unconditionally overwrites existing files
1
27.01.2020, 21:11
cd usr/local/src/ccl/ccl-1.8/x86-headers
printf 'd=%s ; mkdir -p ${d}'$$'/C
     cp ${d}/C/populate.sh ${d}'$$'/C\n' * | sh

Создается каталог с именем ${dir}${current_shells_pid}/C для каждого, который вы показали в выводе ls в вопросе. Затем он копирует нужный файл из исходного кода в целевую директорию.

1
27.01.2020, 21:11

Теги

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