Как найти и распечатать файлы, отсутствующие в каталоге?

Да, в оболочке bashвы можете использовать замену процесса:

minimap -ax map-ont /path/to/fasta.file <( cat *.fastq ) >output.sam

<(... )— это подстановка процесса. Он будет заменен именем пути именованного канала (что-то вроде /dev/fd/XXX), который будет производить вывод команды внутри при чтении из него. Вывод команды в процессе подстановки не сохраняется на диске.

Пока инструменту minimapне нужно прыгать назад и вперед по данным fastq, а просто считывать их последовательно, это, вероятно, будет работать.

Делая это без замены процессов (это также будет работать с shили любой оболочкой POSIX):

mkfifo fastq_data
cat *.fastq >fastq_data &
minimap -ax map-ont /path/to/fasta.file fastq_data >output.sam
rm fastq_data

Это почти то же самое, что и первая команда. Он создает именованный канал и объединяет с ним данные fastq (, catработает как фоновое задание, пока весь его вывод не будет прочитан minimap, а затем завершается ). Затем вызывается инструмент minimapс именованным каналом для данных fastq. Когда это будет сделано, именованный канал будет удален.

Чтение из канала fastq_dataозначает чтение напрямую из команды cat, а не из какого-то временного файла. Опять же, результат catникогда не сохраняется на диске.

Если инструменту minimapпо какой-то причине требуется файл fastq с определенным суффиксом имени файла, это может быть лучшим вариантом. Просто назовите свой именованный канал как data.fastqили аналогичный.

1
09.07.2019, 22:39
3 ответа

Шаг 1. )Создайте список всех применимых каталогов, отсортируйте его в алфавитно-цифровом порядке и убедитесь, что нет дубликатов. Сохраните список во временном файле:

find /work/user/folder1/ [...] -type d | sort | uniq > all_directories.txt

Шаг 2. )Создайте список всех *.gridфайлов.

find /work/user/folder1/ [...] -name *.grid > grid_files.txt

Шаг 3. )Проработайте список *.gridфайлов, возьмите имя каталога каждого файла и снова убедитесь, что нет дубликатов:

while read FILENAME
do
    echo $(dirname "$FILENAME")
done < grid_files.txt | sort | uniq > dirs_with_gridfiles.txt

Шаг 4. )Запустите эти два списка вместе и снова отсортируйте результат. Теперь каталоги с *.gridфайлами должны быть перечислены ровно дважды каждый, а каталоги без *.gridфайлов ровно один раз каждый. Таким образом, вы можете указать uniqсообщать только о неповторяющихся -строках:

cat all_directories.txt dirs_with_gridfiles.txt | sort | uniq -u > dirs_with_no_gridfile.txt

Вот и получишь.

0
27.01.2020, 23:41

Используйте findдля вызова find!

find. -type d \( -exec sh -c 'cd "$0"; find. \( -name. -o -prune \) -name "*.grid" | grep -q.' {} \; -o -print \)

Это соответствует стандарту POSIX -, благодаря этому ответу:

Кроме того, это будет работать независимо от пробелов, специальных символов или даже новых строк в именах файлов или каталогов.:)

(Н.Б. :Если у вас есть специальные символы или новые строки в именах ваших каталогов, вы должны изменить этот последний -printпервичный на любое действие, которое вы хотите выполнить с каталогами, поскольку вы не сможете безопасно разобрать получившийся напечатанный список, если вы просто используете -print.)

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

find. -type d \
  \( \
    -exec sh -c '
      cd "$0";
      find. \( -name. -o -prune \) -name "*.grid" |
        grep -q.
    ' {} \; \
    -o -print \
  \)
1
27.01.2020, 23:41

Если у вас Bash v4 (или выше ), я думаю, вы также можете сделать это с помощью одного цикла, ищущего все *.gridфайлы, плюс один внутренний цикл для всех каталогов, чтобы перечислить, в каких каталогах есть файлы, а в каких не надо. В Bash v4 мы используем одну из его опций, которая обычно отключена.

(
# 'globstar' enables '**' expansions, which instructs
# the shell to search all and below recursively
shopt -s globstar

# Note that '**' is implicitly recursive, no need to specify
# depth. If you do want to specify precise depth, then use a
# '*/' for each wanted depth, like '*/*/*/' for 3 depths
for f in /work/user/folder1/**/*.grid; do
    f="${f##*/}"  # strip directory from found name
    printf '\nNow looking for: %s\n' "$f"
    # A simple '**/' returns directories only
    for d in /work/user/folder1/**/; do
        # simple existence test
        [ -e "${d}${f}" ] && \
            printf '    present in %s\n' "$d" || \
            printf 'not present in %s\n' "$d"
    done
done
)

К сожалению, синтаксис **не соответствует POSIX.

Однако, если вы знаете точную глубину поиска, просто уберите команду shoptи превратите каждый **/в точную глубину, выраженную как */повторений, и это должно хорошо работать и в оболочках POSIX..

0
27.01.2020, 23:41

Теги

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