Генерируйте несколько символьных ссылок при поддержании структуры каталогов

Можно также использовать grep:

grep "91_987986787688899.*successful" file

Если Ваш файл не имеет очень странный формат, Вы могли также, вероятно, просто сделать это:

awk '/91_987986787688899.*successful/' file

Нет никакой потребности в print $0, это подразумевается.

2
28.10.2015, 03:31
4 ответа

Я бы генерировал команды с помощью awk, а затем передал бы их в bash:

find /data/DIV5/SASC/e042_ctcl/input/*/Clean_data/*/*/*.fq.gz -type f | \
awk '{printf "mkdir -p `dirname %s`\nln -s %s ./%s \n", substr($0, 27), $0, substr($0, 27)}'

Это генерирует список команд, я бы сначала контролировал их, а затем передал бы их в bash. Полная команда будет:

find /data/DIV5/SASC/e042_ctcl/input/*/Clean_data/*/*/*.fq.gz -type f | \
awk '{printf "mkdir -p `dirname %s`\nln -s %s ./%s \n", substr($0, 27), $0, substr($0, 27)}' | bash
2
27.01.2020, 21:50

Уродливый и хрупкий, но он должен выполнить свою работу:

find /data/DIV5/SASC/e042_ctcl/input/*/Clean_data/*/*/*.fq.gz -type f -print0 | \
  xargs -0 -n 1 \
    sh -c 'mkdir -p "$PWD/`dirname $0`"; ln -s "$0" "$PWD/`dirname $0`"'

Вдохновленный ответом хаоса , я придумал эту альтернативу, которая также убирает ненужные директории :

find /data/DIV5/SASC/e042_ctcl/input/*/Clean_data/*/*/*.fq.gz -type f   \
     -printf 'mkdir -p "${PWD}/%h"; ln -s "%p" \\\n\t"${PWD}/%h"\n'   | \
sed 's#/data/DIV5/SASC/e042_ctcl##'                                   | \
sh -

Она генерирует требуемые mkdir и ln команды:

mkdir -p "${PWD}//data/DIV5/SASC/e042_ctcl/input/x/Clean_data/0/a"; ln -s "/data/DIV5/SASC/e042_ctcl/input/x/Clean_data/0/a/foobar.fq.gz" \
    "${PWD}//data/DIV5/SASC/e042_ctcl/input/x/Clean_data/0/a"

Затем он удаляет из них ненужные каталоги с помощью sed, в результате чего:

mkdir -p "${PWD}//input/x/Clean_data/0/a"; ln -s "/data/DIV5/SASC/e042_ctcl/input/x/Clean_data/0/a/foobar.fq.gz" \
    "${PWD}//input/x/Clean_data/0/a"

Команда ln начинается в той же строке, что и mkdir, и продолжается в следующей строке, чтобы сохранить источник в целости и сохранности во время обрезки пункта назначения. Для их печати на той же строке или на каждой отдельной строке потребовался бы более сложный сценарий sed.

Пояснение из -документации для find, из -printf параметров:

%p. Имя файла (не абсолютное имя пути, а имя файла в том виде, в котором он был найден - т.е. как относительный путь от одной из начальных точек)

%h. Ведущие каталоги имени файла (все, кроме последнего элемента и косой черты перед ним). Если имя файла не содержит косой черты (например, потому что он был назван в командной строке и находится в текущей рабочей директории), то "%h" расширяется до "...". Это предотвращает расширение "%h/%f" до "/foo", что было бы удивительно и, вероятно, нежелательно.

4
27.01.2020, 21:50

У меня сложилось впечатление, что вы ищете такой инструмент, как GNU Stow.

GNU Stow - это менеджер ферм symlink, который берет отдельные пакеты программ и/или данных, расположенные в отдельных каталогах файловой системы, и делает вид, что они установлены в одном и том же месте. Например, /usr/local/bin может содержать симлинки к файлам в пределах /usr/local/stow/emacs/bin, /usr/local/stow/perl/bin и др, а также рекурсивно для любых других подкаталогов, таких как .../share, .../man, и так далее.

Проверьте, совпадает ли она со случаем использования.

2
27.01.2020, 21:50

Zsh имеет удобную функцию zmv . Сначала загрузите его (вы можете сделать это из своего .zshrc или из командной строки для использования в одном сеансе):

autoload -U zmv
alias zcp='zmv -C'
alias zln='zmv -L'

Чтобы воссоздать лес символических ссылок так же просто:

 zln -s '/data/DIV5/SASC/e042_ctcl/(input/*/Clean_data/*/*/*.fq.gz)' '$1'

Если вы хотите рекурсивно перемещаться по каталогам Clean_data вместо того, чтобы идти ровно на два уровня в глубину:

 zln -s '/data/DIV5/SASC/e042_ctcl/(input/*/Clean_data/**/*.fq.gz)' '$1'

Существует большое ограничение: при этом не будут созданы необходимые подкаталоги. Вы можете сделать это, определив и используя функцию-оболочку для ln , которая создает каталоги по мере необходимости.

ln_s_mkdir () {
  mkdir -p -- ${(P)#}
  ln -s "$@"
}
 zmv -p ln_s_mkdir '/data/DIV5/SASC/e042_ctcl/(input/*/Clean_data/**/*.fq.gz)' '$1'

Вы можете ускорить выполнение команды, используя команды zsh internal mkdir и ln (которые не загружаются по умолчанию, потому что у них меньше параметров что утилиты GNU можно найти в большинстве систем).

zmodload -F zsh/files b:zf_ln b:zf_mkdir
ln_s_mkdir () {
  zf_mkdir -p -- ${(P)#}
  zf_ln -s "$@"
}
 zmv -p ln_s_mkdir '/data/DIV5/SASC/e042_ctcl/(input/*/Clean_data/**/*.fq.gz)' '$1'
1
27.01.2020, 21:50

Теги

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