在.odt文件列表中找到一个字符串并打印匹配的行

时间:2019-01-21 15:52:10

标签: bash

我正在尝试找到在odt文件列表中查找单词的方法。我的意思是odt文件中有一个字。 然后,我想查看哪些文件包含该单词以及与该单词匹配的行(或至少在它之前的某些单词,在其之后的某些单词)。

这是我到目前为止所拥有的:

for file in *.odt; do unzip -c "$file" | grep -iq "searched_word" && echo "$file"; done

这会向我显示包含我要查找的单词的文件的名称:

filename1.odt
filename2.odt

但是,我也无法成功看到与文件中单词匹配的行,例如:

the is the first line with searched_word blabla : /path/filename1.odt
the is the second line with searched_word blabla : /path/filename2.odt

有什么主意吗?

3 个答案:

答案 0 :(得分:1)

将grep输出读取到变量中,并使用相同的语句回显

grep -i "searched_word" | read x && echo "$x:$file"

$ cat filename1.odt
the is the first line with searched_word blabla
fsds
sdgdf
$ cat filename2.odt
gfdgj gdflgjdfl
the is the second line with searched_word blabla
fdg gdfgdf
$ for file in *.odt; do ; cat $file  | grep -i "searched_word" | read x && echo "$x:$file" ; done
the is the first line with searched_word blabla:filename1.odt
the is the second line with searched_word blabla:filename2.odt

否定情况

$ for file in *.odt; do ; cat $file  | grep -i "QQQQQ" | read x && echo "$x:$file" ; done
$

答案 1 :(得分:0)

一种方法是让grep打印您的文件名,即使您使用的是stdin。有以下选项:

   -H, --with-filename
          Print the file name for each match.  This is the default when there is more than one file to search.

   --label=LABEL
          Display input actually coming from standard input as input coming from file LABEL.  This is especially useful when implementing tools like zgrep, e.g., gzip -cd foo.gz |  grep  --label=foo  -H
          something.  See also the -H option.

   -n, --line-number
          Prefix each line of output with the 1-based line number within its input file.

   -a, --text
          Process a binary file as if it were text; this is equivalent to the --binary-files=text option.

因此,您只需设置--label=$file -Ha -n即可获得输出,就好像直接运行grep一样。

您需要犯-H ...容易犯的错误,但是如果没有,则会出现“只有1个输入文件”,因此不会打印任何标签。

如果grep的启发式方法确定输入看起来像二进制,则可能需要-a。

实际上,为什么不能直接运行grep?某些grep安装会自动解压缩.gz文件。

答案 2 :(得分:0)

Java 1.8的基本实现:

package app;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.Namespace;
import org.jdom2.filter.Filters;
import org.jdom2.input.SAXBuilder;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;


/**
 *  OfficeSearch
 */
public class OfficeSearch
{
    private final Set<String> searchSet = new HashSet<>();
    private static OfficeSearch INSTANCE = new OfficeSearch();

    //
    // main
    //
    public static void main(String[] args) {
        INSTANCE.execute(args);
    }

    //
    //  execute
    //
    private void execute(String[] args) {
        if (args.length > 1) {
            for (int i=1; i<args.length; i++) {
                searchSet.add(args[i].toLowerCase());
            }
            try {
                Files.list(Paths.get(args[0])).sorted().
                    map(Path::toFile).
                    filter(this::is_odt).
                    forEach(this::search);
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
        else {
            System.out.println("Usage: OfficeSearch <directory> <search_term> [...]");
        }

    }

    //
    //  is_odt
    //
    private boolean is_odt(File file) {
        if (file.isFile()) {
            final String name = file.getName();
            final int dotidx = name.lastIndexOf('.');
            if ((0 <= dotidx) && (dotidx < name.length() - 1)) {
                return name.substring(dotidx + 1).equalsIgnoreCase("odt");
            }
        }
        return false;
    }

    //
    // search
    //
    private void search(File odt) {
        try (ZipFile zip = new ZipFile(odt)) {
            final ZipEntry content = zip.getEntry("content.xml");
            if (content != null) {
                final SAXBuilder builder = new SAXBuilder();
                final Document doc = builder.build(zip.getInputStream(content));
                final Element root = doc.getRootElement();
                final Namespace office_ns = root.getNamespace("office");
                final Namespace text_ns = root.getNamespace("text");
                final Element body = root.getChild("body", office_ns);
                if (body != null) {
                    boolean found = false;
                    for (Element e : body.getDescendants(Filters.element(text_ns))) {
                        if ("p".equals(e.getName()) ||
                            "h".equals(e.getName())) {
                            final String s = e.getValue().toLowerCase();
                            for (String p : searchSet) {
                                if (s.contains(p)) {
                                    if (!found) {
                                        found = true;
                                        System.out.println("\n" + odt.toString());
                                    }
                                    System.out.println(e.getValue());
                                }
                            }
                        }
                    }
                }
            }
        }
        catch (IOException | JDOMException e) {
            e.printStackTrace();
        }
    }

}
相关问题