@Oli был прав, это была просто проблема с микшером. По какой-то причине мой внутренний микрофон был установлен на «mute» по умолчанию.
Я исправил его, перейдя на вкладку «gnome-volume-control», «Input» и сняв флажок «mute». [!d1 ]
Code-golfed пока читается только двумя командами и двумя регулярными выражениями:
mkdir -p {a..z} '#'
prename -n 's|^[[:alpha:]]|\l$&/$&|;s|^[0-9]|#/$&|' [[:alnum:]]?*
Если у вас есть огромное количество файлов для перемещения, слишком много, чтобы вписаться в список аргументов процесса (да, есть предел, и это может быть всего несколько килобайт), вы можете сгенерировать список файлов с помощью другой команды и канала, чтобы prename, e. g.:
find -mindepth 1 -maxdepth 1 -name '[[:alnum:]]?*' -printf '%f\n' |
prename -n 's|^[[:alpha:]]|\l$&/$&|;s|^[0-9]|#/$&|'
Это имеет дополнительное преимущество, не пытаясь переместить буквальное имя файла [[:alnum:]]?*, если никакие файлы не соответствуют шаблону glob. find также допускает гораздо больше критериев соответствия, чем раскол оболочки. Альтернативой является установка опции оболочки nullglob и закрытие стандартного потока ввода prename .1
. В обоих случаях удалите переключатель -n, чтобы фактически переместить файлы, а не просто показать, как они
Добавление: вы можете снова удалить пустые каталоги с помощью:
rmdir --ignore-fail-on-non-empty {a..z} '#'
1 shopt -s nullglob; prename ... <&-
Если вы не возражаете против zsh, функции и пары команд zmv:
mmv() {echo mkdir -p "${2%/*}/"; echo mv -- "$1" "$2";}
autoload -U zmv
zmv -P mmv '([a-zA-Z])(*.ttf)' '${(UC)1}/$1$2'
zmv -P mmv '([!a-zA-Z])(*.ttf)' '#/$1$2'
Функция mmv делает каталог и перемещает файл. zmv затем предоставляет сопоставление и подстановку шаблонов. Во-первых, перемещая имена файлов, начинающиеся с алфавита, а затем все остальное:
$ zmv -P mmv '([a-zA-Z])(*.ttf)' '${(UC)1}/$1$2'
mkdir -p A/
mv -- abcd.ttf A/abcd.ttf
mkdir -p A/
mv -- ABCD.ttf A/ABCD.ttf
$ zmv -P mmv '([!a-zA-Z])(*.ttf)' '#/$1$2'
mkdir -p #/
mv -- 123.ttf #/123.ttf
mkdir -p #/
mv -- 七.ttf #/七.ttf
Запустите снова без определения echo в mmv для фактического выполнения перемещения.
Я не разработал хороший способ сделать имена каталогов прописными буквами (или переместить файлы с прописными буквами), хотя вы могли бы сделать это впоследствии с помощью rename ...
mkdir {a..z} \#; for i in {a..z}; do for f in "$i"*; do if [[ -f "$f" ]]; then echo mv -v -- "$f" "$i"; fi; done; done; for g in [![:alpha:]]*; do if [[ -f "$g" ]]; then echo mv -v -- "$g" \#; fi; done
[d1 ] или более читаемо: mkdir {a..z} \#;
for i in {a..z}; do
for f in "$i"*; do
if [[ -f "$f" ]]; then
echo mv -v -- "$f" "$i";
fi
done
done
for g in [![:alpha:]]*; do
if [[ -f "$g" ]]; then
echo mv -v -- "$g" \#
fi
done
Удалите echo после тестирования, чтобы фактически переместить файлы
И затем
rename -n 'y/[a-z]/[A-Z]/' *
удалите -n, если он хорошо выглядит после тестирования и запускается снова.
Следующие команды в каталоге, содержащем шрифты, должны работать, если вы хотите использовать из-за пределов каталога хранения шрифтов, измените for f in ./* на for f in /directory/containing/fonts/*. Это очень основанный на оболочке метод, поэтому он довольно медленный и также нерекурсивный. Это создаст только каталоги, если есть файлы, которые начинаются с совпадающего символа.
target=/directory/to/store/alphabet/dirs
mkdir "$target"
for f in ./* ; do
if [[ -f "$f" ]]; then
i=${f##*/}
i=${i:0:1}
dir=${i^}
if [[ $dir != [A-Z] ]]; then
mkdir -p "${target}/#" && mv "$f" "${target}/#"
else
mkdir -p "${target}/$dir" && mv "$f" "${target}/$dir"
fi
fi
done
Как один лайнер, снова из каталога хранения шрифтов:
target=/directory/to/store/alphabet/dirs; mkdir "$target" && for f in ./* ; do if [[ -f "$f" ]]; then i=${f##*/}; i=${i:0:1} ; dir=${i^} ; if [[ $dir != [A-Z] ]]; then mkdir -p "${target}/#" && mv "$f" "${target}/#"; else mkdir -p "${target}/$dir" && mv "$f" "${target}/$dir" ; fi ; fi ; done
Метод, использующий find с аналогичной строковой манипуляцией с использованием расширения параметра bash, который будет рекурсивным и должен быть несколько быстрее, чем версия чистой оболочки:
find . -type f -exec bash -c 'target=/directory/to/store/alphabet/dirs ; mkdir -p "$target"; f="{}" ; i="${f##*/}"; i="${i:0:1}"; i=${i^}; if [[ $i = [[:alpha:]] ]]; then mkdir -p "${target}/$i" && mv "$f" "${target}/$i"; else mkdir -p "${target}/#" && mv "$f" "${target}/#"; fi' \;
Или более читаемо:
[ f4]Сопоставьте каждое имя файла с именем каталога с помощью tr, затем mkdir и mv:
find /src/dir -type f -print0 |
xargs -0 -I{} bash -c \
'dir=/dest/$(basename "{}" | cut -c1 | tr -C "a-zA-Z\n" "#" | tr "a-z "A-Z"); mkdir -p $dir; mv "{}" $dir'