2013-06-12 3 views
4

Я пытаюсь создать wc -l весь каталог, а затем отобразить имя файла в эхо с количеством строк.Файл с наибольшим количеством строк в каталоге NOT bytes

Чтобы добавить к моему разочарованию, каталог должен исходить из переданного аргумента. Итак, не глядя глупо, может кто-то сначала сказать мне, почему простой wc -l $1 не дает мне счет строки для каталога, который я вводил в аргумент? Я знаю, что не понимаю его полностью.

Кроме того, мне нужна проверка, если приведенный аргумент не является каталогом или существует более одного аргумента.

Как всегда, вы великолепны.

+2

'man wc' сказал бы вам' wc [OPTION] ... [FILE] ... '. 'wc' работает с файлами, а не с каталогами. – devnull

+0

@devnull, строго говоря, каталоги - это еще один тип файлов. В системах, которые позволяют открывать и читать каталоги, такие как обычные файлы, 'wc' будет сообщать количество символов новой строки в содержимом этих каталогов (но это не то, что OP ожидает и не будет полезно) –

+0

Вы хотите найти файл с наибольшим количеством строк или отобразить файлы с их количеством строк. –

ответ

6

wc работает на файлы, а не каталоги так, если вы хотите рассчитывать слово на все файлы в каталоге, вы бы начать с:

wc -l $1/* 

С различными циркуляциями, чтобы избавиться от общего количества, разбирайтесь и извлечь только самый большой, вы могли бы в конечном итоге с чем-то вроде (разбито на несколько строк для удобства чтения, но должны быть введены в одной строке):

pax> wc -l $1/* 2>/dev/null 
     | grep -v ' total$' 
     | sort -n -k1 
     | tail -1l 

2892 target_dir/big_honkin_file.txt 

Как проверки, вы можете проверить количество передаваемых параметров к вашему скрипту с чем-то вроде:

if [[ $# -ne 1 ]] ; then 
    echo 'Whoa! Wrong parameteer count' 
    exit 1 
fi 

и вы можете проверить, если это каталог с:

if [[ ! -d $1 ]] ; then 
    echo 'Whoa!' "[$1]" 'is not a directory' 
    exit 1 
fi 
1

Я пытаюсь к Wc -l весь каталог, а затем отобразить имя файла в эхо с количеством строк.

Вы можете сделать find на каталог и использовать -exec опцию для запуска wc -l. Что-то вроде этого:

$ find ~/Temp/perl/temp/ -exec wc -l '{}' \; 
wc: /Volumes/Data/jaypalsingh/Temp/perl/temp/: read: Is a directory 
     11 /Volumes/Data/jaypalsingh/Temp/perl/temp//accessor1.plx 
     25 /Volumes/Data/jaypalsingh/Temp/perl/temp//autoincrement.pm 
     12 /Volumes/Data/jaypalsingh/Temp/perl/temp//bless1.plx 
     14 /Volumes/Data/jaypalsingh/Temp/perl/temp//bless2.plx 
     22 /Volumes/Data/jaypalsingh/Temp/perl/temp//classatr1.plx 
     27 /Volumes/Data/jaypalsingh/Temp/perl/temp//classatr2.plx 
     7 /Volumes/Data/jaypalsingh/Temp/perl/temp//employee1.pm 
     18 /Volumes/Data/jaypalsingh/Temp/perl/temp//employee2.pm 
     26 /Volumes/Data/jaypalsingh/Temp/perl/temp//employee3.pm 
     12 /Volumes/Data/jaypalsingh/Temp/perl/temp//ftp.plx 
     14 /Volumes/Data/jaypalsingh/Temp/perl/temp//inherit1.plx 
     16 /Volumes/Data/jaypalsingh/Temp/perl/temp//inherit2.plx 
     24 /Volumes/Data/jaypalsingh/Temp/perl/temp//inherit3.plx 
     33 /Volumes/Data/jaypalsingh/Temp/perl/temp//persisthash.pm 
0

Это то, что вы хотите?

> find ./test1/ -type f|xargs wc -l 
     1 ./test1/firstSession_cnaiErrorFile.txt 
     77 ./test1/firstSession_cnaiReportFile.txt 
    14950 ./test1/exp.txt 
     1 ./test1/test1_cnaExitValue.txt 
    15029 total 

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

find $your_complete_directory_path/ -type f|xargs wc -l 
+0

Следует отметить, что предполагается, что '$ your_directory' является относительным путем ('./ 'добавлено к нему) и не содержит подстановочные или пустые символы (' $ your_directory' не цитируется) и что ни одно из имен файлов не содержит пробелов или кавычек символов ('xargs' без' -0'). –

+0

@sch Обновлено ...... – Vijay

0

Чтобы найти файл с большинством строк в текущем каталоге и его подкаталогах, с zsh:

lines() REPLY=$(wc -l < "$REPLY") 
wc -l -- **/*(D.nO+lined[1]) 

Это определяет функцию lines, которая будет использоваться в качестве функции сортировки glob, которая возвращает в $REPLY количество строк файла, путь указан в $REPLY.

Затем мы используем zsh «s рекурсивная подстановка **/* найти правильные файлы (.), численно (n) отсортированных в обратном порядке (O) с lines функции (+lines) и выберите сначала одну [1]. (D, чтобы включить dotfiles и trapass dotdirs).

Выполнение этого со стандартными утилитами немного сложно, если вы не хотите делать предположения о том, какие имена файлов символов могут содержать (например, newline, space ...). С GNU инструментов, найденных в большинстве дистрибутивов Linux, это немного проще, так как они могут иметь дело с NUL прекращено строки:

find . -type f -exec sh -c ' 
    for file do 
    size=$(wc -c < "$file") && 
     printf "%s\0" "$size:$file" 
    done' sh {} + | 
    tr '\n\0' '\0\n' | 
    sort -rn | 
    head -n1 | 
    tr '\0' '\n' 

Или с Zsh или GNU Баш синтаксисом:

biggest= max=-1 
find . -type f -print0 | 
    { 
    while IFS= read -rd '' file; do 
     size=$(wc -l < "$file") && 
     ((size > max)) && 
     max=$size biggest=$file 
    done 
    [[ -n $biggest ]] && printf '%s\n' "$max: $biggest" 
    } 
1

Хороший вопрос!

Я видел ответы. Некоторые из них довольно хороши. find ...|xrags является моим самым предпочтительным. Его можно было бы упростить, используя синтаксис find ... -exec wc -l {} +. Но есть проблема. Когда буфер командной строки заполнен, вызывается wc -l ... и каждый раз, когда строка <number> total является принтером. Поскольку wc не имеет аргумента, чтобы отключить эту функцию, необходимо переопределить wc. Для того, чтобы отфильтровать эти строки с не приятно:

Так что мой полный ответ

#!/usr/bin/bash 

[ $# -ne 1 ] && echo "Bad number of args">&2 && exit 1 
[ ! -d "$1" ] && echo "Not dir">&2 && exit 1 
find "$1" -type f -exec awk '{++n[FILENAME]}END{for(i in n) printf "%8d %s\n",n[i],i}' {} + 

Или используя меньше временного пространства, но немного больше кода в :

find "$1" -type f -exec awk 'function pr(){printf "%8d %s\n",n,f}FNR==1{f&&pr();n=0;f=FILENAME}{++n}END{pr()}' {} + 

Разное

  • Если это shou ld не вызывается для подкаталогов, затем добавьте -maxdepth 1 до -type в .
  • Это довольно быстро. Я боялся, что это будет намного медленнее, чем версия find ... wc +, но для каталога, содержащего 14770 файлов (в нескольких поддирерах), версия запускает 3,8 с и версия запускается в течение 5 сек.
  • и Рассматривают не \nконечные линии по-разному. Последняя строка, закончившаяся без \n, не учитывается . Я предпочитаю считать это .
  • Он не печатает пустые файлы
+0

Обратите внимание, что в названии вопроса указано _find самый большой файл_ –

+0

@sch: Но в вопросе нет ни слова об этом. – TrueY

0

Вот один, который работает для меня с мерзавца Баш (mingw32) под окнами:

find . -type f -print0| xargs -0 wc -l 

Это будет список файлов и счетчик строк в текущем каталог и поддиректории. Вы также можете направлять вывод в текстовый файл и импортировать его в Excel при необходимости:

find . -type f -print0| xargs -0 wc -l > fileListingWithLineCount.txt 
Смежные вопросы