В общем случае пустая строка не обозначает текущий каталог ни в командах оболочки, ни в системных вызовах. В некоторых старых системах это так, но не в 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)
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
сниппете. Как уже указывалось в комментариях, по крайней мере один из них не соответствует вашему образцу входного файла.
Распечатывается последняя найденная запись с таким же ключом.
Записи печатаются в случайном порядке.