Легко подсчитывать слова в списке файлов в папке после команды 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
но это пострадает от двух ошибок:
- список аргументов слишком длинный
- если бы это было не слишком долго, это дало бы 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
).