Легко подсчитывать слова в списке файлов в папке после команды grep-v

Я пытался сделать сценарии, которые я пишу, проще и проще.

существует множество способов записи получить количество слов всех файлов в папке или даже всех файлов подкаталогов папки.

например, я мог бы написать

wc */* 

и я мог бы получить такой результат (это желаемый результат):

   0        0        0 10.53400000/YRI.GS000018623.NONSENSE.vcf
   0        0        0 10.53400000/YRI.GS000018623.NONSTOP.vcf
   0        0        0 10.53400000/YRI.GS000018623.PFAM.vcf
   0        0        0 10.53400000/YRI.GS000018623.SPAN.vcf
   0        0        0 10.53400000/YRI.GS000018623.SVLEN.vcf
   2       20      624 10.53400000/YRI.GS000018623.SVTYPE.vcf
   2       20      676 10.53400000/YRI.GS000018623.SYNONYMOUS.vcf
  13      130     4435 10.53400000/YRI.GS000018623.TSS-UPSTREAM.vcf
 425     4250   126381 10.53400000/YRI.GS000018623.UNKNOWN-INC.vcf

но если слишком много файлов, я могу получить сообщение об ошибке, как это:

-bash: /usr/bin/wc: Argument list too long

так, я можно сделать переменную и сделать одну папку за раз, например:

while read $FOLDER
do
    wc $FOLDER/* >> outfile.txt
done < "$FOLDER_LIST"

таким образом, это идет от одной строки до 5 просто так.

далее, в одном случае, я хочу использовать grep -v во-первых, затем вынести слово подсчета, как так:

grep -v dbsnp */* | wc

но это пострадает от двух ошибок:

  1. список аргументов слишком длинный
  2. если бы это было не слишком долго, это дало бы wc для все файлы сразу, а не в файл.

Итак, резюмируя, я хотел бы иметь возможность сделать это:

grep -v dbsnp */* wc > Outfile.txt
awk '{print ,} Outfile.txt > Outfile.summary.txt

и вернуть его, как я показал выше.

есть очень простой способ сделать это? Или я смотрю на петлю как минимум? Опять же, я знаю 101 способ сделать это так же, как и остальные из нас, используя сценарий 4-10 строк, но я хотел бы иметь возможность просто ввести 2 строки в командную строку...и мои знания о оболочке еще недостаточно глубоки, чтобы понять, какими путями это возможно. позвольте то, что я прошу от ОС.

изменить -

было предложено решение:

find -exec grep -v dbsnp {} ; | xargs -n 1 wc

это решение приводит к следующему выводу:

wc: 1|0:53458644:AMBIGUOUS:CCAGGGC|-16&GCCAGGGCCAGGGC|-18&GCCAGGGCC|-19&GGCCAGGGC|-19&GCCAGGGCG|-19,.:48:48,48:4,4:0,17:-48,0,-48:0,0,-17:27:3,24:24: No such file or directory
wc: 10: No such file or directory
wc: 53460829: No such file or directory
wc: .: Is a directory
      0       0       0 .
wc: AA: No such file or directory
wc: CT: No such file or directory
wc: .: Is a directory
      0       0       0 .
wc: .: Is a directory
      0       0       0 .

насколько я могу судить, похоже, каждая строка рассматривается как файл. Я все еще просматриваю другие ответы, и спасибо за вашу помощь.

4 ответов


вы упомянули ,что" это не решает проблему возврата wc по пунктам"

следующее:

find -exec wc {} \;

но это не придет с вашим grep фильтр "grep -v"

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

find -exec bash -c  "echo -n {}; grep -v dbsnp {} | wc " \;

у вас слишком много матчей */* таким образом, grep получает длинный список аргументов. Вы можете использовать find чтобы обойти это:

find -exec grep -v dbsnp {} \; | wc

и, возможно, вы тоже хотите избавиться от возможных ошибок обхода:

find -exec grep -v dbsnp {} \; 2> /dev/null | wc

это работает для меня:

grep -or "[a-zA-Z]*" * | cut -d":" -f2 | sort | uniq -c

то, что вы ищете, - алгоритм MapReduce http://en.wikipedia.org/wiki/MapReduce


на основе ответа perreal:

если вы хотите wc файл за файлом, вы можете использовать xargs:

find -exec grep -v dbsnp {} \; | xargs -n 1 wc

xargs может читать стандартные входные данные и строить и выполнять командные строки с ним. Таким образом, он считывает результат вашего входного потока и выполняет wc для каждого отдельного элемента (-n 1).