Можно использовать -o
и измените grep немного
-o, --only-matching
Print only the matched (non-empty) parts of a matching line, with each such
part on a separate output line.
.
ORIGINAL_LAYOUT=`setxkbmap -query | grep -oP '(?<=layout\:\s{5})\w+'`
Мы изменили regex для использования оглядывания так не часть соответствия
В zsh (который можно использовать от Cygwin или Linux), можно использовать спецификаторы шарика для выбора самого большого файла. Это - самый большой файл размером байта, не с точки зрения размеров изображения - — который является, вероятно, правильной вещью здесь, так как это дает изображениям с высоким разрешением полномочия.
for d in /path/to/music/**/*(/); do
rm -f $d/*.jpg(oL[1,-2]N)
mv $d/*.jpg $d/cover.jpg
done
Цикл пересекает все подкаталоги /path/to/music
рекурсивно. (/)
суффикс ограничивает соответствия каталогами. Аргумент rm -f
использование три спецификатора шарика: oL
к виду размером; [1,-2]
сохранить только соответствия до предпоследнего (PATTERN([-1])
последнее соответствие, PATTERN([-2])
предпоследнее соответствие, и PATTERN([1,-2])
список соответствий сначала к предпоследнему содержащему); и N
произвести пустой список, а не оставить шаблон нерасширенным или сообщить об ошибке, если шаблон не соответствует никакому файлу.
Можно получить безопасную ошибку, если остающийся файл уже называют cover.jpg
или если существует нет .jpg
файл в каталоге. Для предотвращения их изменитесь mv
звоните в
[[ -e $d/cover.jpg ]] || mv $d/*.jpg $d/cover.jpg
Вот альтернативный метод, который переименовывает, сначала затем удаляет. Это использует PATTERN1~PATTERN2
синтаксис, который требует extended_glob
опция, для выбора файлов то соответствие PATTERN1
но нет PATTERN2
. ((#jpgs))
тесты, если jpgs
массив содержит по крайней мере один элемент.
setopt extended_glob
for d in /path/to/music/**/*(/); do
jpgs=($d/*.jpg(oL))
((#jpgs)) || continue
[[ $jpgs[1] == */cover.jpg ]] || mv $jpgs[1] $d/cover.jpg
rm -f $jpgs[2,-1]
done
Вот Schwartzian, преобразовывают для Вас:
stat -c "%s %n" *.jpg | sort -n | cut -d " " -f 2- | head -n -1 |
while IFS= read -r filename; do echo rm "$filename"; done
Использовать stat
для вывода размера и имени файла, вида, удаляют поле размера, игнорируют самое большое и выполняют итерации по получающимся файлам.
Используя GNU находят.
#!/usr/bin/env bash
# GNU find + bash4 / ksh93v / zsh
# Get the largest file matching pattern in the given directories recursively
${ZSH_VERSION+false} || emulate ksh
${BASH_VERSION+shopt -s lastpipe extglob}
function getLargest {
typeset -A cur top || return
typeset dir x
for dir in "$2"/*/; do
[[ -d $dir ]] || return 0
getLargest "$1" "${dir%/}" || return
top[size]=-1
find "$dir" -maxdepth 1 -type f -name "$1" -printf '%s\0%f\0' | {
while :; do
for x in cur\[{size,name}\]; do
IFS= read -rd '' "$x" || break 2
done
if (( cur[size] > top[size] )); then
top[size]=${cur[size]} top[name]=${cur[name]}
fi
done
mv -- "${dir}"{"${top[name]}",cover.jpg}
rm -f -- "${dir}"!(cover.jpg)
}
done
}
# main pattern dir [ dir ... ]
function main {
if [[ -n $1 ]]; then
typeset dir pattern=$1
shift
for dir; do
[[ -d $dir ]] || return
getLargest "$pattern" "$dir"
done
else
return 1
fi
}
main \*.jpg /path/to/music/