Как вычесть число вывода w c -l в скрипте bash? - PullRequest
0 голосов
/ 08 марта 2020

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

Вот мой сценарий:

#!/bin/bash

for file in "$1"/*;
do
    cat "$file" | while read line;
do
    countContent1="$(grep '\(<Content>\)' | wc -l)"
    countContent2="$(grep '\(showReview\)' | wc -l)"
    valuableReviews="$(($countContent1-$countContent2))"
    echo "$(b=${file##*/}; echo ${b%.*})" $valuableReviews
done
done | sort -r -n -k 2

обратите внимание, что и <content>, и showReview находятся на одной строке в файле. Вывод - это только номер строки, содержащей <content>, вычитания нет.

Вот часть файла:

<Author>lass=
<Content>Empfehlenswert....   showReview(11348491, 'full');  
<Date>Sep 28, 2006
<No. Reader>-1
<No. Helpful>-1
<Overall>4
<Value>-1
<Rooms>4
<Location>-1
<Cleanliness>5
<Check in / front desk>-1
<Service>4
<Business service>-1

Ответы [ 2 ]

1 голос
/ 08 марта 2020

Это имеет больше смысла, если вы вынимаете внутреннее while read l oop:

#!/bin/bash

for file in "$1"/*; do
    countContent1=$(grep -c '[<]Content[>]' <"$file")
    countContent2=$(grep -c 'showReview' <"$file")
    valuableReviews=$((countContent1 - countContent2))
    b=${file##*/}; b=${b%.*}
    echo "$b $valuableReviews"
done | sort -r -n -k 2

Примечание:

  • Мы перенаправляем "$file" в каждый копия grep, поэтому grep считает содержимое в файле вместо содержимого в stdin .
  • Мы удалили while read l oop целиком и позволяем grep перебирать отдельные строки каждого файла, вместо того, чтобы пытаться сделать это в bash. (Следовательно, теперь мы запускаем grep дважды для файла , а не дважды для строки каждого файла ).
  • Мы не используем подстановки команд без необходимости. $(...) имеет значительное снижение производительности (ниже, чем при выполнении внешней команды, но все же намного выше, чем при выполнении всего в родительском процессе).

Было бы еще быстрее заменить все программа с одной копией awk:

#!/bin/awk -f

/[<]Content[>]/ {
  ++allContent
  if ($0 ~ /showReview/) {
    ++valuableReviews
  }
}
FILENAME != fn {
  if(fn) { print(fn, ": ", (allContent - valuableReviews)); }
  allContent = 0; valuableReviews = 0; fn = FILENAME;
}
END {
  print(fn, ": ", (allContent - valuableReviews))
}

... называемая ./theAwkScript "$1"/*

0 голосов
/ 09 марта 2020
    :>cat file1.txt
    <Author>lass=
    <Content>Empfehlenswert....   showReview(11348491, 'full');
    <Date>Sep 28, 2006
    <No. Reader>-1
    <No. Helpful>-1
    <Overall>4
    <Value>-1
    <Rooms>4
    <Location>-1
    <Cleanliness>5
    <Check in / front desk>-1
    <Service>4
    <Business service>-1

    :>echo -e  "Lines with content $(grep -c Content file1.txt)\nLines with showReview $(grep -c showReview file1.txt)"
    Lines with content 1
    Lines with showReview 1
    :>
grep -c Content file1.txt -- Count of lines matching pattern 
$() --> Run some command 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...