Фильтровать список файлов по целочисленному массиву?

В прошлом у меня также была проблема с цветовыми кодами ANSI, которые мешали навигации в командной строке; вам нужно поместить коды ANSI вокруг \[ \], чтобы командная оболочка знала, как (, а не ), учитывать их как часть входной строки.

Как в:

export PS1="\[\e[0;35m\][\u@\h \W]\$\[\e[m\] "
echo -e "\[\e[0;35m\]YOU ARE ON THE LIVE SERVER !!\[\e[0m\]"

Некоторое объяснение того, почему оболочке нужны \[и\]:Чтобы отобразить подсказку в правильных позициях в символьной матрице терминала, оболочке необходимо знать правильную длину строки подсказки, которая равна количеству печатных символов, т.е. е. не управляющие символы или последовательности символов.

Однако оболочка не знает, какие последовательности символов терминал считает пригодными для печати. Следовательно, необходимо предоставить оболочке подсказки, чтобы различать печатаемые и не -печатаемые последовательности, что является целью \[и \].

2
19.05.2019, 03:14
4 ответа

В цикле:

shopt -s nullglob

files=()
for number in "${clipnumbers[@]}"; do
    printf -v pattern 'clip%s-*.png' "$number"
    files+=( $pattern )
done

Это повторяет числа и создает для каждого шаблон подстановки имени файла. Шаблон расширяется, чтобы добавить имена файлов, соответствующие ему, в массив files. Параметр оболочки nullglobзаставляет не -совпадающие шаблоны расширяться до нуля (, а не оставаться нерасширенными ).


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

patterns=()
for number in "${clipnumbers[@]}"; do
    printf -v pattern 'clip%s-*.png' "$number"
    patterns+=( -o -name "$pattern" )
done

find. -type f \( "${patterns[@]:1}" \) -exec action-to-perform-on-files {} \;

:1удаляет начальный -oиз списка в patternsв расширении.

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

6
27.01.2020, 21:49

Использование GNUgrepиprintf:

grep -F $(printf '%s\n' "${clipnumbers[@]}") clip?????-randomlongstring.png

Что можно присвоить такому массиву:

files=($(grep -F $(printf '%s\n' "${clipnumbers[@]}") clip?????-randomlongstring.png))
1
27.01.2020, 21:49

Опция #1

Аналогично ответу Кусалананды , но с расширением массива вместо цикла:

настройка

$ touch clip12710-x.png  clip30443-x.png  clip57592-x.png  clip76672-x.png  clip93493-x.png
$ declare -a array=([0]="30443" [1]="76672" [2]="42424")

Обратите внимание, что массив содержит только два элемента, которые должны совпадать; есть имена файлов с клипами, которые , а не присутствуют, и есть номера клипов в array, которые не , а не существуют в качестве имен файлов.

исполнение

$ shopt -s nullglob
$ pfiles=( "${array[@]/#/clip}" )
$ oIFS="$IFS"
$ IFS=
$ pfiles=( ${pfiles[@]/%/-*.png} )
$ IFS="$oIFS"
$ declare -p pfiles
declare -a pfiles=([0]="clip30443-x.png" [1]="clip76672-x.png")

Обратите внимание на тщательное включение двойных -кавычек в первое присваивание и отсутствие двойных -кавычек во второе присваивание. Начальное присваивание преобразует массив чисел "array" в массив "pfiles" частичных имен файлов путем добавления строки clipк каждому элементу. Второе назначение добавляет подстановочный знак -*.pngк каждому элементу массива; отсутствие кавычек в этом назначении позволяет оболочке разделить каждый элемент на$IFS(обычно пробел, табуляцию и новую строку ), но мы временно переопределили IFS, чтобы он был пустым. Затем оболочка также "подставляет" результаты, чего мы и хотим здесь --, чтобы расширить имена "clip... *-png" в любые совпадающие имена файлов. При установленном параметре оболочки nullglobлюбые не соответствующие -подстановочные знаки отбрасываются. Конечным результатом является массив файлов pfiles, соответствующих номерам клипов из исходного массива.


Опция #2

(ab )использовать расширенное подстановочное значение:

shopt -s extglob nullglob
declare -a array=([0]="30443" [1]="76672" [2]="42424")
oIFS="$IFS"
IFS='|'
p="${array[*]}"
IFS="$oIFS"
pfiles=( clip@($p)-*.png )

Это работает путем установки IFS на символ вертикальной черты |, чтобы последующее присвоение pиз array[*]соединяло элементы arrayвертикальной чертой (первый символ $IFS в этой точке ). Каналы — это разделители, которые требуются расширенному синтаксису подстановки bash между параметрами в шаблоне расширенной подстановки.Последняя строка расширяется до массива файлов, соответствующих созданному нами расширенному шаблону глобуса :

.
  • начните сclip
  • содержат один из заданных паттернов (номера клипов ), теперь содержащиеся в переменнойp
  • затем -затем что-нибудь
  • и заканчивается.png

Параметр оболочки nullglobтребуется, если ваш массив клипов не перекрывается ни с какими существующими именами файлов.

3
27.01.2020, 21:49

Сzsh:

clipnumbers=(01234 33333)
files=(clip$^clipnumbers-*.png(N.))

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

.
files=(clip(${(j:|:)~clipnumbers})-*.png(N.))
2
27.01.2020, 21:49

Теги

Похожие вопросы