Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos 如何grep多个术语并按搜索顺序输出?_Macos_Unix_Command Line_Grep - Fatal编程技术网

Macos 如何grep多个术语并按搜索顺序输出?

Macos 如何grep多个术语并按搜索顺序输出?,macos,unix,command-line,grep,Macos,Unix,Command Line,Grep,我尝试了一些方法,但似乎没有取得任何进展——我有一个文本文件,其中包含一些数据行,我希望从该文件中获得一些数据行。每行都有一个唯一的标识符,我可以grep 如果我使用 grep 'name1\|name2\|name3\|name4' file.txt > newfile.txt 它完成了任务,并将我想要的行变灰,但是,我想要按照我指定的顺序排列这些行-从这个示例中,我想要先命名1行,然后命名2行,然后命名3行,最后命名4行 但是,比如说,在我的原始文件中,行的顺序是name2,后面是n

我尝试了一些方法,但似乎没有取得任何进展——我有一个文本文件,其中包含一些数据行,我希望从该文件中获得一些数据行。每行都有一个唯一的标识符,我可以grep

如果我使用

grep 'name1\|name2\|name3\|name4' file.txt > newfile.txt
它完成了任务,并将我想要的行变灰,但是,我想要按照我指定的顺序排列这些行-从这个示例中,我想要先命名1行,然后命名2行,然后命名3行,最后命名4行

但是,比如说,在我的原始文件中,行的顺序是name2,后面是name4,后面是name3,后面是name1,输出文件中的行似乎也是这样的顺序

有没有办法轻松订购grep

ID是按块排序的,因此,例如,所有名为1的行都相邻出现


谢谢你的建议

一个蹩脚的解决方案可能是。。多次运行grep命令(也许你可以将它粘贴到shell脚本中并多次运行)

希望这有帮助

使用循环从文件中读取单词 给grep一个单词文件,例如:

root
lp
syslog
nobody
您可以使用读取循环重复grep另一个文件中的固定字符串。例如,使用bashshell的默认REPLY变量和存储在
/tmp
目录中的word文件,这将起作用:

while read; do
    grep --fixed-strings "$REPLY" /etc/passwd
done < /tmp/words
读取时
;做
grep--固定字符串“$REPLY”/etc/passwd
完成
笔记
  • 发布的示例不会阻止多个匹配,但它将确保按照
    /tmp/words
    中定义的顺序进行匹配
  • 出于性能原因,该示例使用GNU grep和固定字符串。您的里程数可能会随其他grep和正则表达式而变化

  • 您可以使用Awk数组

    awk 'BEGIN { k[1]="name1"; k[2]="name2"; k[3]="name3" }
    { for (i=1; i<4; ++i) if ($0 ~ k[i]) m[i]=(m[i]?m[i] RS:"") $0 }
    END { for(i=1; i<4; ++i) if (m[i]) print m[i] }' file
    

    这可能比同等的Awk脚本更有效。它每行只能找到一个匹配项,因此它并不完全相同。

    perl更适合这种搜索和打印

    perl -lne '/name1/?push @a,$_:
              (/name2/?push @b,$_:
              (/name3/?push @c,$_:
               /name4/?push @d,$_:next));
              END{print join "\n",@a,@b,@c,@d}' your_file
    
    测试代码如下:

    > cat temp
    1 name1
    2 name2
    3 name3
    4 name1
    5 name4
    6 name2
    7 name1
    > perl -lne '/name1/?push @a,$_:(/name2/?push @b,$_:(/name3/?push @c,$_:/name4/?push @d,$_:next));END{print join "\n",@a,@b,@c,@d}' temp
    1 name1
    4 name1
    7 name1
    2 name2
    6 name2
    3 name3
    5 name4
    > 
    
    好问题:)

    列表项

    我也在看同样的命令,但现在我明白了

    步骤1:为您的grep搜索创建文件。只需在文件中粘贴grep单词,在一行中粘贴一个grep关键字。例如,我将文件mySearch.txt

    更多mySearch.txt

    名称2
    名称3
    名称1
    名称4
    名称2
    名称1

    步骤2:现在使用此命令
    grep-Fwf mySearch.txt file.txt>newfile.txt

    cat file.txt|grep-Fwf mySearch.txt>newfile.txt


    Thais命令将首先打印所有带有name2的行,然后是name3,依此类推,并在newfile.txt的末尾打印name1行。

    恐怕
    grep
    不支持此要求。您可能需要循环浏览单词,并一次grep一个单词。一个简单的改进方法是对“name1”“name2”“name3”“name4”中的单词使用
    ;dogrep“$word”file.txt;完成>新建文件.txt
    。。。。但从表面上看,Awk显然更漂亮。Awk中缺少嵌套数组有点悲哀,但在Perl中使用backref作为数组键的能力是我编写第二个版本的真正原因。我想这也可以在Awk中完成,尽管不是很优雅。谢谢你的建议!我真的希望有一个简单一点的东西-我会调查这些建议!
    perl -lne '/name1/?push @a,$_:
              (/name2/?push @b,$_:
              (/name3/?push @c,$_:
               /name4/?push @d,$_:next));
              END{print join "\n",@a,@b,@c,@d}' your_file
    
    > cat temp
    1 name1
    2 name2
    3 name3
    4 name1
    5 name4
    6 name2
    7 name1
    > perl -lne '/name1/?push @a,$_:(/name2/?push @b,$_:(/name3/?push @c,$_:/name4/?push @d,$_:next));END{print join "\n",@a,@b,@c,@d}' temp
    1 name1
    4 name1
    7 name1
    2 name2
    6 name2
    3 name3
    5 name4
    >