sed使部分模式匹配

时间:2019-12-02 10:01:23

标签: bash sed grep

我的任务是:输入六个字符串和一个文件名,从这六个字符串中拉出至少满足三个模式的所有行。

例如:./test.sh p1 p2 p3 p4 p5 p6 file.txt,因此行aabbbp1p3p5p4匹配,但oop4op2ooo不匹配。

那么在命令行中几行写命令sedgrep的重点是什么? (awk也可以尝试,但是我对此不太熟悉)

我最后要做的就是征求排列。

4 个答案:

答案 0 :(得分:0)

这就是我要怎么做。我更改了参数的顺序,因此第一个参数是文件名,所有其他参数都是模式:

#!/bin/bash

[[ "$#" -lt 4 ]] && { echo "You need at least 4 arguments. A filename and 3 patterns"; exit 3;}
filename="$1" && shift
patterns=( $@ )

[[ ! -f "$filename" ]] && { echo "File '$filename' does not exist"; exit 4;}

matches=0
while read line
do
    matches=0
    for p in "${patterns[@]}"
    do
        grep -q "$p" <( echo "$line" ) && (( matches++ ))
    done
    [[ "$matches" -ge 3 ]] && echo "$line";
done <<< "$( cat $filename )"

exit 0

希望有帮助!

答案 1 :(得分:0)

理想情况下,您需要可扩展的高效解决方案。对于脚本编写,这意味着要运行尽可能少的外部命令(每个外部命令(如grep都需要大量资源来启动)。

以下解决方案将仅读取数据文件6次(每次都是一个grep),计算每行的匹配数,并仅打印> = 3个匹配项的行。

patterns=("$1" "$2" "$3" "$4" "$5" "$6")
file=$7


for p in "${patterns[@]}" ; do grep -- "$p" "$file" ; done |
sort |
uniq -c |
awk '$1 >= 3 { print gensub("^ *[0-9]+ ", "", 1) }'

答案 2 :(得分:0)

无需使用其他工具。
全部重击-

test.sh:

pats=("$1" "$2" "$3" "$4" "$5" "$6") # get the patterns
file="$7"                            # assign the source
while read -r line                   # read each line
do declare -i hits=0                 # initialize hits
   for p in "${pats[@]}"             # loop through patterns
   do case "$line" in                # comparing to input
      *"$p"*) (( hits++ )) ;;        # increment on match
      esac                  
   done
   (( hits > 2 )) && echo "$line"    # print on threshhold
done < "$file"                       # reading from file

file.txt

p1 p2 p3 p4 p5 p6
p1 p2 p3 p4 p5
p1 p2 p3 p4
p1 p2 p3
p1 p2
p1
.

已执行:

$: ./test.sh p1 p2 p3 p4 p5 p6 file.txt
p1 p2 p3 p4 p5 p6
p1 p2 p3 p4 p5
p1 p2 p3 p4
p1 p2 p3

答案 3 :(得分:0)

这可能对您有用(GNU并行):

parallel '(({1}<{2})) && (({2}<{3})) && echo "/p{1}/{/p{2}/{/p{3}/b}}"' ::: {1..6} ::: {2..6} ::: {3..6} |
sed -f - -e 'd' filename.txt

这将过滤掉filename.txt中来自集合{p1,p2,p3,p4,p5,p6}中3个或更多匹配项的所有行。