bash получить номер wc -l и отобразить в одной команде? - PullRequest
2 голосов
/ 06 апреля 2011

Я почти уверен, что это будет очевидно, но в настоящее время я делаю это:

count=`find $dir -type f \( -perm -007 \) -print 2>/dev/null | wc -l`

Это дает мне номер, который я хочу, но ничего не отображается на экране (хотя я бросаюв любом случае убрать строки ошибок).

Есть ли способ сделать это (получить счетчик wc -l в переменную count), одновременно выводя вывод на консоль в одной команде?Я почти уверен, что здесь можно использовать что-то вроде tee, но мой мозг работает не так, как должен.

В противном случае, я предполагаю запись во временный файл и консоль с использованием tee и cat обратно в wc будет работать, но я вполне уверен, что должен быть более элегантный способ сделать это.

edit: Извините, кажется, вопросбыло неясно. Я не хочу показывать счетчик на экране, я хочу показать результат, который я рассчитывал, т.е. вывод из find

Ответы [ 6 ]

5 голосов
/ 06 апреля 2011

Ах, значит, вы хотите напечатать нормальный вывод с числом совпадений в $count?

Попробуйте:

count=`find $dir -type f \( -perm -007 \) -print 2>/dev/null | tee /dev/tty | wc -l`
2 голосов
/ 06 апреля 2011

Хорошо, тогда ответ на обновленный вопрос

Подход tty хорош, но не работает на нетерминалах (например, ssh localhost 'echo hello> / dev / tty' fails)

Это может быть просто

count=`find $dir -type f \( -perm -007 \) -print 2>/dev/null | tee >(cat >&2) | wc -l`

Что эквивалентно

count=`find $dir -type f \( -perm -007 \) -print 2>/dev/null | tee /proc/self/fd/2 | wc -l`

Если вы не хотите / не можете использовать stderror (fd 2) в качестве бокового канала здесь, тогда выможете открыть дубликат оригинального стандартного вывода и обратиться к нему вместо:

exec 3>&1
count=`find $dir -type f \( -perm -007 \) -print 2>/dev/null | tee /proc/self/fd/3 | wc -l`

$ 0,02

1 голос
/ 06 апреля 2011

Вот ответ на ваш уточненный вопрос. Это помещает количество в переменную $ count и показывает результат поиска:

found=$(find $dir type f \( -perm -007 \) -print 2>/dev/null)
count=$(echo -e "$found" | wc -l)
echo -e "$found"
1 голос
/ 06 апреля 2011

Обновление Я добавил еще один ответ после того, как вопрос был обновлен

unset x
echo ${x:="$(find $dir -type f \( -perm -007 \) -print 2>/dev/null | wc -l)"}
echo $x

выход

16
16
0 голосов
/ 06 апреля 2011

Вы можете распечатать вывод команды find на экран, если вы tee вывод команды find на stderr (здесь через анонимный fifo).

Если ваши имена файлов или пути имеют встроенные символы новой строки,Ваш счет пойдет не так.Поэтому используйте функцию -print0 команды find, затем удалите все байты, которые не '\ 0', с помощью команды tr, и, наконец, просто подсчитайте байты '\ 0' с помощью команды wc в самом конце..

# show output of find to screen
count=`find . -type f \( -perm -007 \) -print0 2>/dev/null | tee >(tr '\0' '\n' > /dev/stderr) | tr -dc '\0' |  wc -c`
echo "$count"

# show output of count to screen
count=`find . -type f \( -perm -007 \) -print0 2>/dev/null | tee >(tr -dc '\0' | wc -c > /dev/stderr) | tr -dc '\0' |  wc -c`
echo "$count"
0 голосов
/ 06 апреля 2011

Я не уверен, что полностью понимаю, так как команда find, как написано, не нуждается в круглых скобках и не должна выдавать никаких ошибок, и я не знаю, нужно ли выводить вывод в stdoutили если вы просто хотите, чтобы это работало, в этом случае stderr будет работать так же хорошо.Я бы сделал это:

count=`find $dir -type f -perm -007 -print -fprint /dev/stderr | wc -l`
...