Найти строки, содержащие все ключевые слова в скрипте bash - PullRequest
1 голос
/ 02 декабря 2009

По сути, я хотел бы что-то, что ведет себя аналогично:

cat file | grep -i keyword1 | grep -i keyword2 | grep -i keyword3

Как я могу сделать это с помощью bash-скрипта, который принимает список аргументов ключевых слов переменной длины? Сценарий должен выполнять регистрозависимое сопоставление строк, содержащих все ключевые слова.

Ответы [ 7 ]

3 голосов
/ 02 декабря 2009

Используйте это как скрипт

#! /bin/bash
awk -v IGNORECASE=1 -f <(
  P=; for k; do [ -z "$P" ] && P="/$k/" || P="$P&&/$k/"; done
  echo "$P{print}"
)

и вызвать его как

script.sh keyword1 keyword2 keyword3 < file
1 голос
/ 02 декабря 2009

Попробуйте:

shopt -s nocasematch
keywords="keyword1|keyword2|keyword3"
while read line; do [[ $line =~ $keywords ]] && echo $line; done < file

Редактировать

Вот версия, которая проверяет наличие всех ключевых слов, а не только:

keywords=(keyword1 keyword2 keyword3)    # or keywords=("$@")
qty=${#keywords[@]}
while read line
do
    count=0
    for keyword in "${keywords[@]}"
    do
        [[ "$line" =~ $keyword ]] && (( count++ ))
    done
    if (( count == qty ))
    then
        echo $line
    fi
 done < textlines
1 голос
/ 02 декабря 2009

Я не знаю, насколько это эффективно, и я думаю, что это некрасиво, также для этого может быть какая-то полезность, но:

#!/bin/bash

unset keywords matchlist
keywords=("$@")

for kw in "${keywords[@]}"; do
matchlist="$matchlist /$kw/ &&"
done

matchlist="${matchlist% &&}"

# awk "$matchlist { print; }" < <(tr '[:upper:]' '[:lower:]' <file)
awk "$matchlist { print; }" file

И да, требуется некоторая надежность в отношении специальных символови прочее.Это просто чтобы показать идею.

0 голосов
/ 14 апреля 2019

Вот скрипт под названием search.sh в bash, который будет искать строки в файле или папке по всем указанным ключевым словам:

#!/bin/bash
if [ $# -lt 2 ]; then
    echo "[-] $0 file_to_search/folder_to_search keyword1 keyword2 keyword3 ..."
    exit
fi
all_args="$@"
i=0
results=""  # this will store the cumulative results from each keyword search
for arg in $all_args; do
    if [ $i -eq 0 ]; then
        # first argument is the file/folder to search
        file_to_search="$arg"
        i=$(($i + 1))
    elif [ $i -eq 1 ]; then
        # search the file/folder with first keyword (first search)
        results=`grep --color=always -r -n -i "$arg" "$file_to_search"`
        i=$(($i + 1))
    else
        # now keep searching the results from first search for other keywords
        results=`echo "$results" | grep --color=always -i "$arg"`
        i=$(($i + 1))
    fi
done
echo "$results"

Пример вызова скрипта, приведенного выше, будет искать в файле «tools.txt» ключевые слова «python» и «jira»:

./search.sh tools.txt python jira
0 голосов
/ 03 мая 2010

Я бы сделал это на Perl.

Для поиска всех строк, которые содержат хотя бы одну из них:

perl -ne'print if /(keyword1|keyword2|keyword3)/i' file

Для поиска всех строк, которые содержат все из них:

perl -ne'print if /keyword1/i && /keyword2/i && /keyword3/i' file
0 голосов
/ 02 декабря 2009

Нашел способ сделать это с помощью grep.

KEYWORDS=$@
MATCH_EXPR="cat file"
for keyword in ${KEYWORDS};
do
  MATCH_EXPR="${MATCH_EXPR} | grep -i ${keyword}"
done
eval ${MATCH_EXPR}
0 голосов
/ 02 декабря 2009

вы можете использовать bash 4.0 ++

shopt -s nocasematch
while read -r line
do
    case "$line" in 
        *keyword1*) f=1;;&
        *keyword2*) g=1;;&
        *keyword3*) 
            [ "$f" -eq 1 ] && [ "$g" -eq 1 ] && echo $line;;
    esac
done < "file"
shopt -u nocasematch

или поглазеть

gawk '/keyword/&&/keyword2/&&/keyword3/' file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...