найти: обработать slash специально

Это именно то, для чего был создан fgrep (1) ... или более современно (могут использоваться расширения GNU):

grep -Fwf file1 file2

Из man grep :

   -F, --fixed-strings
          Interpret PATTERN as a  list  of  fixed  strings,  separated  by
          newlines,  any  of  which is to be matched.  (-F is specified by
          POSIX.)
   -f FILE, --file=FILE
          Obtain  patterns  from  FILE,  one  per  line.   The  empty file
          contains zero patterns, and therefore matches nothing.   (-f  is
          specified by POSIX.)
   -w, --word-regexp
          Select  only  those  lines  containing  matches  that form whole
          words.  The test is that the matching substring must  either  be
          at  the  beginning  of  the  line,  or  preceded  by  a non-word
          constituent character.  Similarly, it must be either at the  end
          of  the  line  or  followed by a non-word constituent character.
          Word-constituent  characters  are  letters,  digits,   and   the
          underscore.
1
31.07.2018, 20:36
3 ответа

Вместо этого используйте -regex. Шаблон привязан в начале и в конце, поэтому вам, вероятно, нужно будет использовать .*в начале и в конце. Используйте [^/]*/для замены шаблона *, который не соответствует /. Например:

-regex '.*/sr[^/]*sc.*'

Существует небольшой Perl-скрипт find2perl , который утверждает, что преобразовывает аргументы команды findв эквивалентный Perl-скрипт. Очевидно, что для -pathон будет иметь то же сопоставление с шаблоном, что и для find, но вы можете отредактировать его, чтобы принять другой аргумент, скажем, -glob, который затем будет использовать системный вызов fnmatch()для того, чтобы сделать своего рода подстановку. хочу. Я быстро модифицировал свою версию find2perl, как показано в этом патче :

.
--- /usr/bin/find2perl  2016-02-04 19:28:48.000000000 +0100
+++ /tmp/find2perl      2018-07-31 20:38:10.034175198 +0200
@@ -58,2 +58,4 @@
     $out.= tab. '$File::Find::name =~ /'. fileglob_to_re(shift). "/s$1";
+    } elsif (/^glob$/) {
+        $out.= tab. 'fnmatch("'.(shift).'", $name, FNM_PATHNAME|FNM_PERIOD)';
 } elsif ($_ eq 'perm') {
@@ -236,2 +238,3 @@
 use File::Find ();
+use File::FnMatch qw(:fnmatch);    # import everything

(Строки, начинающиеся с +, показывают 3 добавленные мною строки ). Мне нужно было добавить пакеты perl-App-find2perlи perl-File-FnMatchдля Fedora. Вам нужно будет найти эквивалент в вашей системе.

Затем вы можете запускать такие команды, как

/tmp/find2perl. -glob './sr*sc' | perl
2
27.01.2020, 23:18

Чтобы предотвратить findрекурсию в подкаталоги, используйте флаг -maxdepth

find -maxdepth 1 -name "sr*sc"
1
27.01.2020, 23:18

Некоторые оболочки, такие как zsh, bashи ksh93, поддерживают шаблон подстановки имени файла **. В zshон включен по умолчанию, в то время как bashдолжен быть включен с помощью shopt -s globstarи ksh93с set -o globstar.

Это означает, что вы должны уметь делать, например,

for pathname in./src/**/misc/*.c
    # process "$pathname" here
done

Несколькоfind-подобных тестов, таких как -type f, можно было бы легко включить в это:

for pathname in./src/**/misc/*.c
    [ -f "$pathname" ] || continue  # will not skip symbolic links to regular files though
    # process "$pathname" here
done
1
27.01.2020, 23:18

Теги

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