Это должно быть там. Диски в Linux (и Windows, но неважно ), смонтированыв определенном месте. Эта кнопка позволит вам размонтировать этот диск.
В этом нет ничего плохого, и это может быть полезно. Если он вам не нужен, просто игнорируйте его, но нет причин его удалять.
bash выполняет каждую команду конвейера в отдельной подоболочке, если вы не включите параметр оболочки lastpipe
# bash requires job control to be disabled for lastpipe setting
set +m
shopt -s lastpipe
declare -i sum=0
find. -name '*.js' -print0 | while IFS= read -d '' -r name; do
(( sum += $(wc -l < "$name") )) # redirect the file into wc for easier output
done
echo $sum
Подстановки процессов удобны для решения этой проблемы с подоболочкой:
declare -i sum=0
while IFS= read -d '' -r name; do
(( sum += $(wc -l < "$name") )) # redirect the file into wc for easier output
done < <(
find. -name '*.js' -print0
)
echo $sum
Однако это затрудняет чтение программы.
Вот еще один способ сделать это с помощью bash:
sum=0 && while IFS= read -r -d '' f; do let sum+=$(sed -n "\$=" "${f}"); done < <(find. -name '*.js' -print0 2>/dev/random) && echo "$sum"
find... -print0 -- prints with null terminated
IFS= -- deset IFS
read -r -d '' -- -r do not allow backslash escapes, -d '' set delimiter to NULL
let sum+=(..) -- add up sum of sed $= "$f", $: last line, =: line #
Вы хотите, чтобы awk
выполнил сложение и показал результат?
awk '{sum +=$1} END {print sum}'
должно помочь.
В моей библиотеке для bash -скрипты, которые я делаю:
$ find. -type f -name '*.bash' \
| while read -r f ; do wc -l "$f" ; done \
| awk '{sum +=$1} END {print sum}'
и получить результат522
shopt -s globstar; # valid for bash
set --./**/*".js"; cat "$@" | wc -l # for files under `./` directory
shopt -s globstar; # valid for bash
set --./**/*".js" # for files under `./` directory
wc -l "$@" | awk '{sum+=$1} END {print sum-=$1}' # calculate the sum in awk
Но зачем повторно -вычислять сумму, если wc -l
выводит итог в последней строке?:
wc -l "$@" | tail -n 1
Есть несколько элементов, которые можно улучшить:
Часть | awk '{print $1;}'
для выбора только первого поля не требуется, если вы выполняете wc -l <"$f"
вместо wc -l $f
. Простое перенаправление(<
)заставляет wc получить файл на свой стандартный ввод, и у него не будет имени файла для печати. Это уменьшит сценарий до:
найти. | grep ".js" | при чтении -r f; do wc -l <"$f"; сделано
Нет необходимости в вызове grep, если find делает выбор:
найти. -имя '*.js' | при чтении -r f; do wc -l <"$f"; сделано
При чтении удаляются начальные и конечные пробелы из имен файлов.
И на самом деле, find может выполнять команду для каждого файла (неявный цикл):
найти. -name ' *.js' -exec sh -c 'wc -l <"$1"' foo '{}' \;
И даже можно сделать один глобальный вызов wc
вместо одного для каждого файла.
найти.-имя ' *.js' -exec sh -c 'cat "$@" | wc -l' foo '{}' +
Но необходимость повторно -вызывать оболочку для обработки каждого имени файла без каких-либо проблем с пробелами, табуляциями, символами новой строки или подстановочными символами (*,?,[ )указывает на то, что мы можем решить эту проблему непосредственно в оболочке. если нам не нужно какое-то специальное разрешение ссылок.
set -- *.js; cat "$@" | wc -l # for the present directory
Или
shopt -s globstar; # valid for bash
set --./**/*".js"; cat "$@" | wc -l # for files under `./` directory
Вопрос в заголовке касается этой части вашей трубки:
while read -r f; do wc -l $f …
Предполагая, что список файлов находится в списке аргументов($@
)(или может быть внутри некоторого массива ), как указано выше, будет напечатан список файлов с количеством строк в качестве первого поля:
$ printf '%s\n' "$@" | while read -r f; do wc -l "$f"; done
12 filea.js
21 fileb.js
В этот момент вы можете просто добавить новый канал с помощью awk, чтобы выбрать первое поле:
$ printf '%s\n' "$@" | while read -r f; do wc -l "$f"; done | awk '{print $1}'
12
21
Но с тем же успехом вы могли бы напечатать все в одной строке с добавлением +
:
$ printf '%s\n' "$@" |
> while read -r f; do wc -l "$f"; done |
> awk '{printf( "%s+",$1)}'
12+21+
И, добавляя замыкающий 0
, заставьте bc суммировать все это:
$ printf '%s\n' "$@" |
> while read -r f; do wc -l "$f"; done |
> awk '{printf("%s+",$1)}END{print 0}' |
> bc
33
Но, как уже было сказано, вы можете избежать вывода имени файла с помощью wc -l <"$f"`` and you can convert the newlines to
+ , then add a
0 `и заставить bc выполнять вычисления:
$ printf '%s\n' "$@" |
while read -r f; do wc -l <"$f"; done |
{ tr '\n' '+'; echo 0; } |
bc
33
или заставить awk вычислить сумму:
$ printf '%s\n' "$@" |
while read -r f; do wc -l <"$f"; done |
awk '{sum+=$1} END {print sum}'
33