Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.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
Linux grep同时读取行选项_Linux_Bash_Shell - Fatal编程技术网

Linux grep同时读取行选项

Linux grep同时读取行选项,linux,bash,shell,Linux,Bash,Shell,我有一个日志文件.log: toto string1 tata string2 tito string3 tata tati string3 titi string1 tato string2 tati toto ..... tutu string1 tita string2 tita string3 我需要从文件中的每一行提取string1、string2和string3。 这些行可以包含一个、两个或三个字符串 我第一次尝试使用while read LINE do grep: while r

我有一个日志文件.log:

toto string1 tata string2 tito string3
tata tati string3
titi string1 tato string2 tati toto
.....
tutu string1 tita string2 tita string3
我需要从文件中的每一行提取string1、string2和string3。 这些行可以包含一个、两个或三个字符串

我第一次尝试使用while read LINE do grep:

while read line; do 
z_string1=`echo $line | egrep 'string1' | cut -f2 xxx | cut -f1 xxxx`
z_string2=`echo $line | egrep 'string2' | cut -f2 xxx | cut -f1 xxxx`
z_string3=`echo $line | egrep 'string3' | cut -f2 xxx | cut -f1 xxxx`
echo "$z_string1,$z_string2,$z_string3" >> results.csv
done < file.log
读行时
;做
z|u string1=`echo$line | egrep'string1'| cut-f2 xxx | cut-f1 xxxx`
z|u string2=`echo$line | egrep'string2'| cut-f2 xxx | cut-f1 xxxx`
z|u string3=`echo$line | egrep'string3'| cut-f2 xxx | cut-f1 xxxx`
echo“$z_string1、$z_string2、$z_string3”>>results.csv
完成
这就像预期的那样工作,但根本没有优化,而且速度非常慢


谢谢你的帮助

实现这一点的方法有很多。既然您似乎更喜欢shell,那么您应该看看它,它基本上就是为了实现这一点而设计的

Perl也正是为了完成这类任务。一个简单的脚本,带有几个正则表达式以匹配您的搜索词,然后是一个打印


try
grep-oE“string[0-9]”file.log>>results.csv
-o
标志仅将匹配部分作为输出

从我看到的字符串模式正在更改列:

toto string1 tata string2 tito **string3**
tata tati string3
titi string1 tato string2 tati toto
.....
tutu string1 tita string2 tita string3
第2行是第3列,其余的是第2列,因此没有必要依赖列号进行输出,如图所示:

awk -v pattern="string" '{cols=NF; if ( (cols == 6 ) && ($2 ~ pattern))   { print $2 " " $4 " " $6 } }' test.txt 
string1 string2 string3
string1 string2 toto
string1 string2 string3
所以

您可以将其或其部分用于解决方案

    awk -v p1="string1" -v p2="string2" -v p3="string3" 'BEGIN { c1=0; c2=0; c3=0; }
 {if (( $0 ~ p1) || ( $0 ~ p2) || ($0 ~ p3 ))  { 
    for (i=1;i<=NF;i++) {
        if ( $i ~ p1)   { print $i; c1++; 
        } else if  ( $i ~ p2)   { print $i; c2++; 
        } else if ( $i ~ p3)   { print $i; c3++; }
   }  } 
   } END{ print p1"_count:" c1 " "p2"_count:" c2"  "p3"_count:"c3}  ' test.txt

使用
bash
正则表达式匹配捕获字符串(如果存在), 然后打印出来。从您的示例中,我假设您只想打印 如果找不到匹配项,则为空字符串,因此我保留该行为

while read line; do
    [[ $line =~ (string1) ]]; printf "%s," "$BASH_REMATCH"
    [[ $line =~ (string2) ]]; printf "%s," "$BASH_REMATCH"
    [[ $line =~ (string3) ]]; printf "%s\n" "$BASH_REMATCH"
done

这可能不如
perl
awk
解决方案快,但应该是对原始解决方案的改进,因为不需要创建额外的流程;一切都在
bash

中完成,您想只提取stringX还是提取包含stringX的整行?我想只提取stringX
while read line; do
    [[ $line =~ (string1) ]]; printf "%s," "$BASH_REMATCH"
    [[ $line =~ (string2) ]]; printf "%s," "$BASH_REMATCH"
    [[ $line =~ (string3) ]]; printf "%s\n" "$BASH_REMATCH"
done