отфильтровать список частичных дубликатов по условию (ям)

В общем случае пустая строка не обозначает текущий каталог ни в командах оболочки, ни в системных вызовах. В некоторых старых системах это так, но не в POSIX-совместимых системах.

Иногда можно встретить программу, которая использует текущий каталог, когда вы передаете пустую строку, а программа ожидает имя каталога. Иногда это происходит намеренно, а иногда является побочным эффектом добавления абсолютного пути к текущему каталогу, когда заданная строка не начинается со слэша.

Лучше всего было бы оставить ./. Это не принесет никакого вреда.

Если список файлов для

find . … | sed 's!^\./!!'

Обратите внимание, что это искажает некоторые имена файлов, содержащие новые строки. Обычно это не является проблемой для человеческого потребления, а вывод find не подходит для программного потребления, поскольку он неоднозначен. Если вы используете -print0, который подходит для использования в программах, то, вероятно, вам все равно не важен префикс ./.

Вы можете использовать find * ... вместо find . ..., но учтите, что find * имеет ряд недостатков, которые делают его непригодным в общем случае:

  • . опущен.
  • Все точечные файлы (файлы, имя которых начинается с . или ..`) опускаются.
  • Если в текущем каталоге есть файл, имя которого начинается с - (или файл с именем ! или (...), оно будет интерпретировано как опция или предикат командой find.

Первый пункт не имеет значения, если ваш фильтр исключает текущий каталог. Что касается второго пункта, вы можете использовать шаблоны ...?* .[!..]* * * для поиска всех файлов в текущем каталоге, но вам нужно будет проверить, соответствует ли каждый шаблон хотя бы одному файлу, и опустить его, если нет. Это возможно, но очень громоздко. Последний пункт - это стопор. Поэтому find * может подойти для быстрого использования в командной строке, но не используйте его в сценарии.

Альтернативный подход заключается в использовании рекурсивной функции globbing оболочки, например

printf '%s\n' **/*.h

Она должна быть активирована shopt -s globstar в bash и set -o globstar в ksh93, и не существует в базовой POSIX оболочке, такой как dash. Точечные файлы по умолчанию не обходятся; чтобы включить их, сначала заставьте globbing не игнорировать точечные файлы с помощью shopt -s dotglob в bash или FIGNORE='@(.|...)' в ksh93. Также, если совпадений нет, то эта команда выводит шаблон; выполните shopt -s nullglob в bash, чтобы вывести пустую строку, и используйте шаблон ~(N)**/*.h в ksh.

В zsh рекурсивное глобирование включено по умолчанию. Используйте квалификатор glob D для включения точечных файлов и N для печати пустой строки при отсутствии совпадений (по умолчанию zsh выдает ошибку, если шаблон не соответствует ни одному файлу). Вы можете использовать printf, как указано выше, или

print -rl -- **/*.h(DN)

1
16.03.2018, 12:29
1 ответ

Perl one -вкладыш здесь:

perl -F'\t' -lane '$r{$F[0].$F[1].$F[2].$F[3].$F[4]}=$_ if $F[8]=~/\// or $F[8]=~[A-Z] or $F[7]=~/\d/ or $F[6]=~/\b(\d\d)[ACTG]/ and $1<=50; END{print $r{$_} for (keys %r)}' file

Комментарии:

Решение perlбыло предложено при условии, что оно доступно в вашей системе. При необходимости его будет легко переписать в awk, учитывая, что логика и синтаксис очень похожи.

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

Распечатывается последняя найденная запись с таким же ключом.

Записи печатаются в случайном порядке.

0
28.01.2020, 00:38

Теги

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