grep findet keinen Text in dieser Datei

7

Ich habe mit gitdem Quellcode eines Projekts geklont und grepim gesamten Projekt ein Wort gefunden SchemaHandler. grepkonnte das Wort in dieser seltsamen Codedatei nicht finden:

https://github.com/yawlfoundation/yawl/blob/master/src/org/yawlfoundation/yawl/schema/YDataValidator.java

Ja, ich gebe zu, es ist keine Standardtextdatei, kann aber grepauch Zeichenfolgen in Binärdateien finden. In der Tat konnte es das Wort in zwei JAR-Dateien im Projekt finden. Warum ist es mit diesem Text gescheitert?

Der Befehl, den ich verwendet habe, befand sich grep -R SchemaHandler .im Stammverzeichnis des geklonten Projekts.

Ich benutze L ubuntu 18.0.4 und grep3.1

Marco Sulla
quelle
2
Hast du es auch versucht git grep SchemaHandler? Dies erfasst alle Dateien, von denen bekannt ist, dass sie automatisch git.
PerlDuck
1
Ok, git grepfunktioniert, danke. Es ist eine gute Problemumgehung. Aber die Tatsache, dass grepes nicht funktioniert, verwirrt mich.
Marco Sulla
Das ist eine ganz normale Textdatei, abgesehen von der eingebetteten \r\r.
Terdon

Antworten:

8

Es findet es. Das Problem ist, dass die Datei einen Wagenrücklauf ( \r) hat, wodurch der Dateiname vom Terminal ausgeblendet wird. Vergleichen Sie diese beiden Befehle, um zu veranschaulichen, was ich meine:

printf "foobar\n"

und

printf "foo\rbar\n"

Dies ist, was jeder drucken sollte:

$ printf "foobar\n"
foobar
$ printf "foo\rbar\n"
bar

Der zweite Befehl druckt immer noch das foo, aber das \rbewirkt , dass das Terminal zum Zeilenanfang zurückkehrt, sodass es überschrieben wird. Sie können es sehen, wenn Sie odFolgendes verwenden:

$ printf "foo\rbar\n" | od -c
0000000   f   o   o  \r   b   a   r  \n
0000010

Ähnliches passiert, wenn Sie Folgendes ausführen grep -R:

$ git clone https://github.com/yawlfoundation/yawl
$ cd yawl
$ grep -R  SchemaHandler . | grep YDataValidator
 }   }   return schema ;    .replaceAll("type=\"", "type=\"xs:"); xmlns:xs");pes, soonn) e;

Auf den ersten Blick scheinen diese Ergebnisse seltsam. Wie kommt es, dass eine Zeile, die die Zeichenfolge nicht zu enthalten scheint, YDataValidatorvon der zurückgegeben wird grep YDataValidator? Die Antwort ist die \r. Diese Zeile stammt tatsächlich aus der YDataValidator.javaDatei, aber der Dateiname wird durch die Datei verdeckt \r. Sie können dies deutlicher sehen, wenn Sie grepnur die passende Zeichenfolge und einige Zeichen um sie herum drucken:

$ grep -PRo '.{10}SchemaHandler.{10}' . | grep YDataVal
 * @a/org/yawlfoundation/yawl/schema/YDataValidator.java:d using a SchemaHandler.
./src/org/yawlfoundation/yawl/schema/YDataValidator.java:  private SchemaHandler handler;
./src/org/yawlfoundation/yawl/schema/YDataValidator.java:ler = new SchemaHandler(schema);
./src/org/yawlfoundation/yawl/schema/YDataValidator.java:          SchemaHandler handler =
./src/org/yawlfoundation/yawl/schema/YDataValidator.java:      new SchemaHandler(DOMUtil.g

Hier wird der Name korrekt angezeigt , da \rdie 10 Zeichen unmittelbar um eine der 5 Instanzen von SchemaHandlerin nicht vorhanden YDataValidator.javasind. Ihr ursprünglicher Befehl hat die gesamte Datei zurückgegeben (die gesamte Datei ist nur eine Zeile, durch \rdie unter Linux keine Zeilenumbrüche definiert werden). Sie haben also eine lange Zeile gesehen, die aufgrund der Datei verstümmelt wurde \r.

Sie können dies überprüfen, indem Sie Folgendes ausführen:

$ grep SchemaHandler ./src/org/yawlfoundation/yawl/schema/YDataValidator.java 
}   }   return schema ;    .replaceAll("type=\"", "type=\"xs:"); xmlns:xs");pes, soonn) e;

Und dann vergleichen Sie die Ausgabe mit dem, was Sie erhalten, wenn Sie alle \rdurch Zeilenumbrüche ersetzen :

$ grep SchemaHandler ./src/org/yawlfoundation/yawl/schema/YDataValidator.java | tr '\r' '\n'
/*
 * Copyright (c) 2004-2012 The YAWL Foundation. All rights reserved.
 * The YAWL Foundation is a collaboration of individuals and
 * organisations who are committed to improving workflow technology.
 *
 * This file is part of YAWL. YAWL is free software: you can
 * redistribute it and/or modify it under the terms of the GNU Lesser
 * General Public License as published by the Free Software Foundation.
 *
 * YAWL is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
 * Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with YAWL. If not, see <http://www.gnu.org/licenses/>.
 */

package org.yawlfoundation.yawl.schema;

import org.jdom2.Element;
import org.yawlfoundation.yawl.elements.data.YVariable;
import org.yawlfoundation.yawl.exceptions.YDataValidationException;
import org.yawlfoundation.yawl.schema.internal.YInternalType;
import org.yawlfoundation.yawl.util.DOMUtil;
import org.yawlfoundation.yawl.util.JDOMUtil;
import org.yawlfoundation.yawl.util.StringUtil;

import javax.xml.XMLConstants;
import java.util.*;

/**
 * This class serves as a validation mechanism for the specification specific
 * schema and the instance data from either the net or a task. This is performed
 * by taking the data available at the various validation points and converting
 * it into conventional XML which is then validated using a SchemaHandler.
 *
 * @author Mike Fowler
 *         Date: 05-Jul-2006
 */
public class YDataValidator {

    // Object that performs the real validation on XML documents
    private SchemaHandler handler;

    /**
     * Constructs a new validator and handler. The
     * handler is not ready for use until validateSchema
     * has been called.
     * @param schema a W3C XML Schema
     */
    public YDataValidator(String schema) {
        this.handler = new SchemaHandler(schema);
    }

    /**
     * Compiles and determines the validity of the current schema
     * @return true if the schema compiled without error.
     */
    public boolean validateSchema() {
        return handler.compileSchema();
    }

    /**
     * Validates a single data variable
     *
     * @param variable to be validated
     * @param data XML representation of variable to be validated
     * @param source
     * @throws YDataValidationException if the data is not valid
     */
    public void validate(YVariable variable, Element data, String source)
            throws YDataValidationException {
        List<YVariable> vars = new ArrayList<YVariable>(1);
        vars.add(variable);
        validate(vars, data, source);
    }

    /**
     * Validates a collection of variables against the schema. This is achieved by
     * temporarily adding a schema element declaration for the data. This avoids
     * attempting to create a new schema containing only the relevant data types.
     *
     * @param vars variables to be validated
     * @param data XML representation fo the variables to be validated
     * @param source
     * @throws YDataValidationException if the data is not valid
     */
    public void validate(Collection vars, Element data, String source)
            throws YDataValidationException {
        try {
            String schema = ensurePrefixedSchema(handler.getSchema());
            org.w3c.dom.Document xsd = DOMUtil.getDocumentFromString(schema);
            String ns = XMLConstants.W3C_XML_SCHEMA_NS_URI;

            //need to determine the prefix for the schema namespace
            String prefix = ensureValidPrefix(xsd.lookupPrefix(ns));

            org.w3c.dom.Element element = xsd.createElementNS(ns, prefix + "element");
            element.setAttribute("name", data.getName());

            org.w3c.dom.Element complex = xsd.createElementNS(ns, prefix + "complexType");
            org.w3c.dom.Element sequence = xsd.createElementNS(ns, prefix + "sequence");

            ArrayList varList = new ArrayList(vars);
            Collections.sort(varList);               // sort on YParameter ordering value

            for (Object obj : varList) {
                YVariable var = (YVariable) obj;
                org.w3c.dom.Element child = xsd.createElementNS(ns, prefix + "element");
                child.setAttribute("name", var.getName());

                String type = var.getDataTypeName();
                if (XSDType.isBuiltInType(type)) {
                    type = prefix + type;
                }
                else if (YInternalType.isType(type)) {
                    type = prefix + type;
                    xsd.getDocumentElement().appendChild(DOMUtil.getDocumentFromString(
                            YInternalType.valueOf(type).getSchemaString()).getDocumentElement());
                }
                child.setAttribute("type", type);

                if (var.isOptional()) {
                    child.setAttribute("minOccurs", "0");
                }

                sequence.appendChild(child);
            }

            complex.appendChild(sequence);
            element.appendChild(complex);
            xsd.getDocumentElement().appendChild(element);

            SchemaHandler handler =
                          new SchemaHandler(DOMUtil.getXMLStringFragmentFromNode(xsd));

            if (! handler.compileSchema()) {
                throw new YDataValidationException(
                    handler.getSchema(),
                    data,
                    handler.getConcatenatedMessage(),
                    source,
                    "Problem with process model.  Failed to compile schema");
            }

            if (! handler.validate(JDOMUtil.elementToString(data))) {
                throw new YDataValidationException(
                    handler.getSchema(),
                    data,
                    handler.getConcatenatedMessage(),
                    source,
                    "Problem with process model.  Schema validation failed");
            }
        }
        catch (Exception e) {
            if (e instanceof YDataValidationException) throw (YDataValidationException) e;
        }
    }

    /**
     * @return String representation of the schema
     */
    public String getSchema() {
        return handler.getSchema();
    }

    /**
     * @return All error/warning messages relating to the last validation/compilation
     */
    public List<String> getMessages() {
        return handler.getMessages();
    }

    /**
     * @return the set of (first-level) type names defined in this schema
     */
    public Set<String> getPrimaryTypeNames() {
        return handler.getPrimaryTypeNames();
    }

    /**
     * Utility method to ensure the prefix is valid (enforces : and
     * defaults to xs:)
     *
     * @param prefix to validate
     * @return validated prefix
     */
    private String ensureValidPrefix(String prefix) {
        if (StringUtil.isNullOrEmpty(prefix)) {
            return "xs:";
        }
        else if (! prefix.endsWith(":")) {
            return prefix + ":";
        }
        return prefix;
    }


    /**
     * A schema may not have a valid prefix if a spec contains no complex types, so
     * this makes sure it gets one in that case
     * @param schema the schema string to check
     * @return a correctly (or defaultly) prefixed schema string
     */
    private String ensurePrefixedSchema(String schema) {
        if (!schema.contains(":schema")) {
            schema = schema.replaceFirst("schema xmlns", "schema xmlns:xs");
            schema = schema.replaceAll("<", "<xs:")
                           .replaceAll("<xs:/", "</xs:")
                           .replaceAll("type=\"", "type=\"xs:");
        }    
        return schema ;
    }
}

Alternativ können Sie die Ausgabe mittels Pipelining an einen Pager wie lessdie zeigen das \rwie ^Mund kann auch helfen, die Linie zu identifizieren , nachdem Sie sind.

Terdon
quelle
Vielen Dank für die Erklärung. Ich fand ich einfach "Workaround" : grep -R SchemaHandler . | less. Wenn Sie es hinzufügen, werde ich Ihre Antwort akzeptieren.
Marco Sulla
@ MarcoSulla, du bist willkommen. Und ich habe eine Zeile über weniger hinzugefügt.
Terdon
0

Vielleicht eher ein Kommentar, aber ich hatte kein Problem damit, grepIhre Datei auszuführen. Ich habe auf Ihren Link geklickt, rawdann mit der rechten Maustaste geklickt und Select Alldann den Text in einer Datei gespeichert und ausgeführt:

$ grep -R SchemaHandler

greptext: * it into conventional XML which is then validated using a SchemaHandler.
greptext:    private SchemaHandler handler;
greptext:        this.handler = new SchemaHandler(schema);
greptext:            SchemaHandler handler =
greptext:                          new SchemaHandler(DOMUtil.getXMLStringFragmentFromNode(xsd));

Hoffentlich kann jemand, der githubhäufig verwendet, beschreiben, warum Rohtext für mich funktioniert und warum das Klonen für andere nicht funktioniert.

WinEunuuchs2Unix
quelle
1
Wahrscheinlich in Rohtext Ihrem Browser oder Texteditor , wo Sie eingefügt, konvertiert das \rzu \n.
Marco Sulla