Скрипт оболочки для поиска файлов с word1 и без word2 - PullRequest
0 голосов
/ 13 мая 2018

Я пытаюсь написать скрипт оболочки, который находит все файлы со словом 1, но без слова 2

Скрипт

echo -e "File name:"
read file
list=$(find "." -type f -name "$file")
co=$(cat $list | wc -l)
if [ $co -eq 0 ]
then
  echo "File not found"
else
  echo "File(s) List"
  echo "$list"
  result=$(grep -v "word2" $list| grep -rHn "word1" $list)
  if [ $? -ne 0 ]
  then
    echo "Word not found"
  else
    echo "File Line Word"
    echo "$result"
  fi
fi

Файл1:

word2@word1

File2:

test@word1

С помощью этого grep я получаю оба файла обратно, но хочу толькоFile2 без word2

Ответы [ 3 ]

0 голосов
/ 14 мая 2018

Ваш скрипт основан на именах файлов без пробелов и переносов.
Ваш скрипт работает неправильно в result=$(grep -v "word2" $list| grep -rHn "word1" $list). Второй grep не будет смотреть на результаты первого grep, так как он имеет $list в качестве аргумента.
Вы хотели

  result=$(grep -rHn "word1" $(grep -lv "word2" $list))

Это по-прежнему не работает, второй grep вернет все файлы, по крайней мере, с одной строкой, отличной от "word2".
Сначала вам нужно найти все файлы, которые нужно исключить, это файлы с «word2». Эти файлы нужно исключить из списка $ {(я использую фигурные скобки, к этому привыкаю).

   grep -vf <(grep -l "word2" ${list}) <(echo ${list} | tr " " "\n" )

В результате

result=$(grep -Hn "word1" 
  $(grep -vf <(grep -l "word2" ${list}) <(echo ${list} | tr " " "\n" )))

Другим способом было бы добавить дополнительные аргументы к вашей команде find (не найти слово2, но найти слово1)

find  "." -type f -name "${file}" ! -exec grep -q "word2" {} \; \
   -exec grep -Hn "word1" {} \; 2>/dev/null
0 голосов
/ 14 мая 2018

Это, вероятно, самый эффективный grep метод:

grep -lv word2 $(grep -l word1 File*)

Выход:

File2

Обратите внимание, что переключатель -l останавливается при первом совпадении, что для больших файлов может сэкономить время.

Чтобы использовать find в этом, избегая ненужных переменных, выполните:

grep -lv word2 $(grep -l word1 $(find . -type f -name "$file") )
0 голосов
/ 14 мая 2018

В вашей строке "result =" есть две ошибки:

  • второй grep должен читать на стандартном вводе (выходе канала), а не в $ list

  • не должно быть рекурсивным

Итак, я бы предложил:

result=$(grep -v "word2" $list| grep -Hn "word1" )
...