Можно также использовать grep
:
grep "91_987986787688899.*successful" file
Если Ваш файл не имеет очень странный формат, Вы могли также, вероятно, просто сделать это:
awk '/91_987986787688899.*successful/' file
Нет никакой потребности в print $0
, это подразумевается.
Я бы генерировал команды с помощью 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
Уродливый и хрупкий, но он должен выполнить свою работу:
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", что было бы удивительно и, вероятно, нежелательно.
У меня сложилось впечатление, что вы ищете такой инструмент, как GNU Stow.
GNU Stow - это менеджер ферм symlink, который берет отдельные пакеты программ и/или данных, расположенные в отдельных каталогах файловой системы, и делает вид, что они установлены в одном и том же месте. Например,
/usr/local/bin
может содержать симлинки к файлам в пределах/usr/local/stow/emacs/bin
,/usr/local/stow/perl/bin
и др, а также рекурсивно для любых других подкаталогов, таких как.../share
,.../man
, и так далее.
Проверьте, совпадает ли она со случаем использования.
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'