GNU/Linux >> Tutoriels Linux >  >> Ubuntu

Grep ne parvient pas à trouver du texte dans ce fichier ?

J'ai cloné avec git le code source d'un projet, et j'ai utilisé grep pour trouver un mot dans tout le projet, SchemaHandler . grep impossible de trouver le mot dans cet étrange fichier de code :

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

Oui, ce n'est pas un fichier texte standard, je l'avoue, mais grep est capable de trouver des chaînes également dans un fichier binaire. En effet, il a pu trouver le mot dans deux fichiers jar du projet. Pourquoi ça a échoué avec ce texto ?

La commande que j'ai utilisée était grep -R SchemaHandler . à la racine du projet cloné.

J'utilise L Ubuntu 18.0.4 et grep 3.1

Réponse acceptée :

Il le trouve. Le problème est que le fichier a un retour chariot (\r ) qui fait que le nom du fichier est masqué par le terminal. Pour illustrer ce que je veux dire, comparez ces deux commandes :

printf "foobar\n"

et

printf "foo\rbar\n"

Voici ce que chacun doit imprimer :

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

La deuxième commande imprime toujours le foo , mais le \r fait revenir le terminal au début de la ligne, elle est donc écrasée. Vous pouvez le voir si vous utilisez od cependant :

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

Une chose similaire se produit lorsque vous exécutez votre 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;

À première vue, ce résultat semble étrange. Comment arrive une ligne qui ne semble pas contenir la chaîne YDataValidator est renvoyé par le grep YDataValidator ? La réponse est le \r . Cette ligne provient en fait de YDataValidator.java fichier, mais le nom du fichier est masqué par le \r . Vous pouvez voir cela plus clairement si vous dites grep pour n'afficher que la chaîne correspondante et quelques caractères autour :

$ 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

Ici, puisqu'il n'y a pas de \r dans les 10 caractères entourant immédiatement l'une des 5 instances de SchemaHandler dans YDataValidator.java , le nom s'affiche correctement. Votre commande d'origine a renvoyé le fichier entier (le fichier entier n'est qu'une ligne séparée par \r qui ne définissent pas les retours à la ligne sous Linux), vous voyiez donc une longue ligne qui était brouillée à cause du \r .

Vous pouvez vérifier en exécutant ceci :

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

Et puis en comparant la sortie à ce que vous obtenez si vous remplacez tous les \r avec saut de ligne :

$ 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 ;
    }
}

Alternativement, vous pouvez rediriger la sortie vers un pager comme less qui affichera le \r comme ^M et peut également vous aider à identifier la ligne que vous recherchez.

Connexes :La meilleure façon de créer un crochet d'arrêt ?
Ubuntu
  1. Comment utiliser la commande Grep pour rechercher du texte dans des fichiers

  2. Commande grep Linux

  3. Comment trouver les fins de ligne dans un fichier texte ?

  4. lien symbolique :trouver tous les fichiers liés à ce fichier

  5. Comment grep \n dans le fichier

Commande Grep sous Linux (Rechercher du texte dans des fichiers)

Comment trouver une chaîne dans un fichier sous Linux

Manipuler du texte avec sed et grep

Comment extraire des adresses e-mail d'un fichier texte sous Linux

Comment rechercher et remplacer du texte, un mot ou une chaîne dans un fichier

Rechercher du texte dans des fichiers sous Linux à l'aide de grep