Толик Панков
hex_laden
............ .................. ................
Толик Панков [userpic]
Linux. Получение списка файлов по маске с игнорированием регистра символов имени файла.

Преамбула


Всем известна команда ls, выводящая список файлов на консоль. Если требуется вывести только файлы с расширением .iso, то в команду подставляется маска файла: ls *.iso
И все бы хорошо, но команда ls, как и другие команды Linux, любит строгое совпадение регистра имен файлов, т.е. если в каталоге есть файлы с расширением .ISO, .Iso и .iso, то ls *.iso выдаст только те, которые с расширением именно что .iso, и проигнорирует остальные. А вот Windows регистр имен файлов глубоко пофиг, хотя, современные версии Windows и сохраняют регистр в имени файлов. Но для аналогичной линуксовой команде ls команды Windows dir, что .ISO, что .Iso, что .iso - равнозначны, и все командой dir *.iso будут выведены.

Чем воспользоваться?


Можно воспользоваться мощной командой find, которая умеет игнорировать регистр имен файлов (на самом деле, она кучу всего умеет, см. в источниках):

find <path> -maxdepth 1 -iname <mask>

где:
<path> - путь к каталогу, в котором производится поиск.
-maxdepth 1 - глубина поиска 1 - только в текущем каталоге, без параметра -maxdepth - во всех подкаталогах и ниже.
-iname - игнорировать регистр имени файла.
<mask> - маска файла

Чтобы обрезать полный путь (а find выдает полный путь к файлу(-ам)) до имени, можно воспользоваться командой

basename <path>

где

<path> - полный путь к файлу

Объединить работу двух команд можно с помощью цикла for

Решение


Создадим отдельную функцию create_list(), принимающую два параметра - путь к каталогу и маску файла, и выдающую список файлов в переменную $FOUNDLST:

create_list() #$1 - dir, $2 - file mask
{
    FOUNDLST=""
    for FLE in $(find $1 -maxdepth 1 -iname $2); do
	if [ -n "$FLE" ]; then
	    FOUNDLST="$FOUNDLST"`basename $FLE`"\n"
	fi
    done
}


Пример использования функции


DIR1="/home/smallwolfie/test/archives"
DIR2="/home/smallwolfie/test/isos"
...
create_list $DIR1 "*.tar.gz"

if [ -z "$FOUNDLST" ]; then
    echo "$DIR1 *.tar.gz not found"
else
    TARGZ=$FOUNDLST
fi

create_list $DIR2 "*.iso"

if [ -z "$FOUNDLST" ]; then
    echo "$DIR2 *.iso not found"
else
    ISO=$FOUNDLST
fi

create_list $DIR2 "*.zip"

if [ -z "$FOUNDLST" ]; then
    echo "$DIR2 *.zip not found"
fi

echo "*.tar.gz:"
echo -e -n "$TARGZ"
echo "-----------"
echo "*.iso:"
echo -e -n "$ISO"


Результат


Ясно, что в тестовой директории archives должны лежать архивы *.tar.gz, а в isos - образы *.iso

/home/smallwolfie/test/archives *.zip not found
*.tar.gz:
one.tar.gz
two.tar.gz
teSt.Tar.gZ
TEST.TAR.GZ
-----------
*.iso:
lamantin.iso
ariar-01-05-2019-install.ISO
smallwolfie@wolfschanze:~/test$


Готовый скрипт


На GitHub
На PasteBin

Источники


1. Команда find в Linux Копия
2. basename
3. Цикл for в bash

Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2019/05/07/linux-poluchenie-spiska-fajlov-po-maske-s-ignorirovaniem-registra-simvolov-imeni-fajla/

Tags: ,
Comments

Молодецъ !
Изучай дальше

Изучай дальше
На том и стоимЪ.
Хотя вот это конкретно попросил студент придумать.