Упорядочить слова в именах файлов по алфавиту с помощью сортировки?

То, что работает , не напрямую зависит от дистрибутива (Gentoo, Debian, RHEL и т. Д.) Или оболочки (ZSH, KSH , BASH) - это зависит от того, какой эмулятор терминала используется, и его настроек: konsole, terminator, urxvt, lx-terminal и т. Д. Дистрибутив может иметь значение, если он использует другую стандартную конфигурацию оболочки (fx. zshrc), и при использовании другой оболочки, которая настраивает оболочку в этом дистрибутиве, может уже обрабатывать ее.

Вот несколько решений для эмулятора терминала:

urxvt / rxvt-unicode (и, возможно, другие):

bindkey "^[Od" backward-word
bindkey "^[Oc" forward-word

terminator, konsole и xterm (и, возможно, другие):

bindkey "^[[1;5D" backward-word
bindkey "^[[1;5C" forward-word

Для более общего подхода вы начинаете на вашем терминале нажмите CTRL-V, а затем комбинацию клавиш, для которой требуется escape-код (имя) - в данном случае комбинации клавиш CTRL-leftarrow и CTRL-rightarrow - и поместите вывод для каждой комбинации клавиш между двумя кавычками .

8
06.08.2017, 20:31
3 ответа

Хороший вопрос!

Вот мой простой bashскрипт для этого:

for file in *.jpg; do 
    afile=( ${file#*)} ); 
    echo mv "$file" "${file%%#*}$(echo $(sort<(printf "%s\n" "${afile[@]%%.*}"))).jpg";
done

Пояснение:

  • Вafile=( ${file#*)} );:мы преобразовываем строку в массив. В этом состоянии оболочка выполняет разбиение слов пробелами, если вы не берете строку в кавычки.

    В${file#*)}(сократить -до -до -первого -префикса):мы удаляем все от начала строки до первого ), увиденного с помощью shell parameter expansion, как это будет результат #wallpaper #4k #googleimages.jpgс учетомfile="Sunrise (2) #wallpaper #4k #googleimages.jpg"

  • В${file%%#*}(сократить -до -до -последнего -суффикса);зачистка начинается с конца до начала строки до последнего #увиденного. это приведетSunrise (2)

  • В${afile[@]%%.*}(сократить -вверх -до -последнего -суффикса):так же, как указано выше, удаление начала с конца до начала строки (здесь в каждом индексированном массиве )до последнего .видели. это даст #wallpaper #4k #googleimages, мы также могли бы использовать ${afile[@]%.*}лучше!

  • Вprintf "%s\n" "${afile[@]%%.*}":мы печатаем элементы массива с символами новой строки ([@], используемыми для индексированного массива ), (почему с новыми строками? Потому что мы будем их сортировать, и мы должны разделить элементы на новые строки)

  • В$(sort<(printf "%s\n" "${afile[@]%%.*}")):мы сортируем элементы (или теги ).

  • В$(echo $(sort<(printf "%s\n" "${afile[@]%%.*}"))):то же самое, что и выше, но мы использовали дополнительную команду echoдля сбора отсортированных элементов в один линейный.

    возможно то же самое с использованием двойного xargsподобного ... |xargs -n1| sort | xargs.
    Пожалуйста, посмотрите пример ниже, чтобы лучше понять этот шаг:

    echo -e "C\n4\nB" |sort
    4
    B
    C
    echo $(echo -e "C\n4\nB" |sort)
    4 B C
    

Наконец, в конце, mvкоманда переименовывает $fileв измененное имя.

Ps:удалите echo mv...перед mv, чтобы выйти из пробного -прогона и выполнить фактическое переименование.

2
27.01.2020, 20:10

Сzsh:

autoload zmv # best in ~/.zshrc
zmv -n '([^#]#)(\#*)(.*)' '$1${(j: :)${(os: :)2}}$3'

(удалить-n(сухой -сухой ход )если устраивает ).

  • [^#]#:0 или более не -#символов(#похоже на *в регулярных выражениях)
  • s: :разделить на пробел
  • o:порядок (сортировка)
  • j: ::соединиться с пробелом.

Итак, мы разделяем часть между первым#(включенным )и последним.(исключенным )по пробелу, сортируем полученный список, который соединяем обратно пробелом.

Рекурсивно:

zmv -n '(**/)([^#]#)(\#*)(.*)' '$1$2${(j: :)${(os: :)3}}$4'

Чтобы разрешить пробелы в именах тегов, мы могли бы разделить по #и обрезать конечные пробелы, отсортировать и объединить по #с помощью:

zmv -n '([^#]#\#)(*)(.*)' '$1${(j: #:)${(os:#:)2}%% #}$3'

Добавьте квалификатор (#qD)glob, если вы также хотите обрабатывать скрытые файлы(Dили файлы )или хотите обрабатывать файлы в скрытых каталогах.

3
27.01.2020, 20:10
#!/bin/bash

for i in dir_for_files/*; do
    filename=${i%%#*}
    sorted_tags=$(grep -o "#[^.]*" <<< "$i" | sort -n | tr '\n' ' ')
    ext=${i#*.}
    echo mv "$i" "${filename}${sorted_tags% }.$ext"
done

Тестирование:

##### Before sorting #####    
$ ls -1 dir_for_files
Note (3) #textfile #notes #important.txt
Sunrise (2) #wallpaper #4k #googleimages.jpg
Sunset (2) #wallpaper #2k #images.jpg

$./sort_tags.sh

##### After sorting #####
$ ls -1 dir_for_files
Note (3) #important #notes #textfile.txt
Sunrise (2) #4k #googleimages #wallpaper.jpg
Sunset (2) #2k #images #wallpaper.jpg
5
27.01.2020, 20:10

Теги

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