Warum scheitert das?
touch "$(printf "a\nb")"; find . -regex './.\n.'
Ich habe auch diese ausprobiert, von denen keine funktioniert:
find . -regextype posix-extended -regex '.\n.'
find . -regextype posix-awk -regex '.\n.'
find . -regextype posix-basic -regex '.\n.'
find . -regextype posix-egrep -regex '.\n.'
Der einzige Weg, wie es zu funktionieren scheint, ist (danke @MichaelMrozek)
find . -regex './.'$'\n''.'
Was gelinde gesagt umständlich ist. Warum scheinen die regulären Ausdrücke von find nicht in der Lage zu sein, damit umzugehen \n
?
Update als Antwort auf die bisherigen Antworten:
OK, ich verstehe, dass dies \n
nicht Teil von ERE ist und dass dies eines meiner Missverständnisse war, sondern den find
Anspruch auf Unterstützung posix-awk
und beides gawk
und mawk
Übereinstimmung \n
wie erwartet:
$ printf "f1l1\nhas newline:f2l1#f1l2 does not:f2l2#" |
mawk -F: 'BEGIN{RS="#"}; ($1~/\n/){print $1}'
f1l1
has newline
Ich habe kein reines awk
zum Testen, also awk
passt POSIX vielleicht nicht zusammen? Andernfalls werden find
keine posix-awk
regulären Ausdrücke implementiert ?
find . -name $'*\n*'
umständlich?-regex
fehlschlägt, nicht Wie finde ich Dateien, die Zeilenumbruch im Dateinamen enthalten? was du perfekt beantwortet hast :).awk
Regex Sprache nicht kennt ,\n
sondern dass derawk
Dolmetscher tut und das ist , warum es übereinstimmt. Daher würde die Implementierung vonawk
regulären Ausdrückenfind
nicht bedeuten, dass dies\n
übereinstimmen sollte. Danke euch allen!Antworten:
Weil GNU find keine
\n
Escape-Sequenz unterstützt. Der reguläre Ausdruck\n
entspricht dem Zeichenn
. GNU find kopiert die traditionelle Emacs-Syntax, die diese Funktion ebenfalls nicht bietet¹.Während GNU find andere Regex-Syntax unterstützt, unterstützt keine Backslash-Letter oder Backslash-Octal, um Steuerzeichen zu kennzeichnen. Sie müssen das Steuerzeichen buchstäblich in das Argument aufnehmen.
Es gibt viele verschiedene Regex-Syntaxen. Weder reguläre reguläre POSIX- Ausdrücke (BRE) noch erweiterte reguläre Ausdrücke (ERE) enthalten
\n
oder Backslash-Octal-Escapezeichen. Beide Definitionen lassen die Bedeutung eines Backslashs unberührt, wenn kein Sonderzeichen folgt. Die Dienstprogramme awk und sed unterstützen beide\n
, um eine neue Zeile zu bedeuten; Dies ist spezifisch für diese Dienstprogramme (und alltäglich, aber wie Sie sehen, nicht universell).Aus einem Shell-Skript können Sie schreiben
¹ Ganz logisch: Für die interaktive Verwendung können Sie jedes Zeichen mit
C-q
eingeben. für die Programmierung\n
als Teil der String-Literal-Syntax vorhanden.quelle
grep
?grep
verwendet standardmäßig BRE oder ERE mit der Option-E
.Sie können eine neue Zeile nicht mit '\ n' abgleichen , da sie in einem regulären Ausdruck keine besondere Bedeutung hat (z. B. Zeilenumbruch), aber Sie können das Zeilenende mit dem regulären Ausdruck $ abgleichen.
quelle
\n
Mit Sicherheit hat es eine Bedeutung in einem regulären Ausdruck, versuchen Sie esprintf "aa\nbb" | perl -ne 'print if /\n/'
, die nur übereinstimmtaa\n
und überspringtbb
zum Beispiel die. Es scheint Unterschiede in der Implementierung zu geben, obwohl die Ursachegrep -P
nicht dazu passt. Aber wie ist das$
hier relevant? Ich möchte eine wörtliche Newline finden,$
die auch ohne eineprintf "aa" | grep 'a$'
\n
hat keine besondere Bedeutung, auch nicht in regulären Perl-Ausdrücken. Es hat jedoch eine besondere Bedeutung in interpolierten Perl-Strings, von denenqr//
es sich um einen Typ handelt. Suche nach\n
inman perlre
...\n
passt zu Zeilenumbrüchen in regulären Ausdrücken. Sie und babaslovesyou haben ganz recht, dass es als solches keine besondere Bedeutung hat, ich meine nur, dass es "passend" ist.\n
in <NL> umgewandelt wird, bevor sie an die Regexp-Engine weitergegeben wird. Dies ist eine Funktion der Perl-String-Analyse.Ich denke, weil die
find
Verwendung derfnmatch
Funktion in der Standard-C-Bibliothek, wenn sieFNM_NOESCAPE
nicht festgelegt ist, ein Backslash-Zeichen im Muster gefolgt von einem anderen Zeichen mit dem zweiten Zeichen in der Zeichenfolge übereinstimmt.Ich überprüfe mit
find (GNU findutils) 4.4.2
undglibc 2.15
, diese Option ist deaktiviert. Checkline 42
infnmatch.h
:quelle
fnmatch
ist für die*.txt
Art der Muster, nicht für die.*\.txt$
Art der regulären Ausdrücke.