Например, отчет jpg будет отображать все файлы, которые называются что-то.jpg. Вот код, над которым я работаю, включая мои вопросы.
function report {
x=`ls *.$1`
num=`ls *.$1 | wc -l`
# Question 1:
# Want to use variable for x to get
# num, but num=$($x | wc -l) didn't work for this purpose.
echo There are $num $1 files
if [ $num -lt 10 ]; then
# Question 2:
# for this part, I want to use "find . -name '*.$1'
# with delimiter . to extract filename from its extension
# and display them (Also maybe need to use while or for loop)
fi
}
report jpg
report html
#!/bin/bash
report(){
local -a n=(*.$1)
echo "There are #${#n[@]} files in '$PWD' with extension '$1'."
if (( ${#n[@]} < 10 )); then
find . -maxdepth 1 -type f -name "*.$1" -printf %f\\n | sed -e 's/\.[^.]*$//'
fi
}
report $1
Использование:./script.sh jpg
Отвечать на Ваши вопросы конкретно:
Q1. средства выражения $x | wc -l
"выполняют команду $x
и передают результаты по каналу к wc -l
". Для передачи по каналу эти содержание из $x
к wc
Вы могли использовать num=`echo "$x" | wc -l`
или (использование удара здесь строка ) num=`wc -l <<< "$x"`
.
Однако форма "обратной галочки" замены команды удерживается от использования - лучше для вырабатывания привычку использования $( ... )
т.е.
num=$(wc -l <<< "$x")
Примечание, что это даст неправильное количество, если какие-либо имена файлов будут содержать символы новой строки (которому их позволяют в Linux).
Q2. В [1 113], одинарные кавычки (иначе 'трудно заключает в кавычки') приблизительно [1 114] предотвратят расширение [1 115], таким образом find
будет искать имена файлов, заканчивающиеся буквально в [1 117]. Для разрешения расширения [1 118] при предотвращении преждевременного расширения [1 119] используйте двойные кавычки (иначе "мягкие кавычки"), т.е. "*.$1"
Вы, вероятно, захотите ограничить поиск каталогом верхнего уровня вместо того, чтобы убывать в подкаталоги (еще, результаты будут несовместимы с количеством, полученным от [1 121]):
find . -maxdepth 1 -name "*.$1"
<час> Однако , вот то, как я сделал бы это - принятие bash
оболочка:
report() {
shopt -s nullglob
local ext="$1"
set -- *."$ext"
printf 'There are %d %s files' $# "$ext"
if (( $# > 0 && $# < 10 )); then
printf '\t%s\n' "$@"
fi
}
Это избегает Ловушка Bash № 1 (анализирующий вывод [1 123] вместо того, чтобы использовать шарик оболочки) и использует оболочку set
встроенный для чтения соответствия именам файлов в $@
позиционный массив параметров. Таким образом, можно использовать $#
для подсчета количества файлов однозначно (даже если они содержат новые строки - где передача по каналу ls
к [1 128] дала бы неправильное количество), и нет никакой потребности использовать отдельное find
команда для получения имен соответствия снова и снова.
, Если Вы хотите отобразить имена файлов без [1 142] расширение, можно заменить $@
в printf
с [1 132], который удаляет самую короткую запаздывающую подстроку, соответствующую .*
от каждого элемента массива с помощью [1 140] расширение параметра .
, Хотя я принял решение использовать (( ... ))
арифметическая конструкция для тестирования количества файлов, нет ничего неправильно с использованием POSIX [ $# -le 10 ]
или [ $# -lt 10 ]
, если Вы предпочитаете. Дополнительное $# > 0
тест должен только сохранить вывод симпатичным, когда нет никаких файлов данного расширения.
Вы могли легко расширить функцию для принятия нескольких расширений при помощи массива для расширений:
function report {
shopt -s nullglob
local exts=( "$@" )
for ext in "${exts[@]}"; do
set -- *."$ext"
printf 'There are %d %s files' $# "$ext"
if (( $# > 0 && $# < 10 )); then
printf ': \n'
printf '\t%s\n' "$@"
else
printf '.\n'
fi
done
}
использование В качестве примера:
$ report txt jpg foo
There are 71 txt files.
There are 4 jpg files:
b.jpg
foo.jpg
inv_logpolar.jpg
logpolar.jpg
There are 0 foo files.