정렬을 사용하여 파일 이름의 단어를 알파벳순으로 정렬하시겠습니까?

정렬을 사용하여 파일 이름의 단어를 알파벳순으로 정렬하시겠습니까?

Bash에서 일괄적으로 파일 이름을 바꾸고 명령을 사용하여 sort파일 내용을 정렬하는 방법에 대한 튜토리얼을 읽을 때 이 둘을 결합하는 방법을 알 수 없었습니다.

프로그램이 수행하는 방식과 유사하게 파일 이름의 태그를 사용하여 내용이 정렬된 디렉토리가 있습니다.라벨 공간일을 잘 처리하십시오. 파일을 만들거나 다운로드할 때 파일 이름 끝에 생각나는 태그를 추가합니다. 예는 다음과 같습니다.

Sunrise (2) #wallpaper #4k #googleimages.jpg

이제 태그 앞이나 뒤(예: 사진 제목이나 파일 확장자)에 영향을 주지 않고 태그가 알파벳순으로 정렬되도록 이러한 모든 파일을 검토하고 이름을 바꾸고 싶습니다. 따라서 위의 내용은 다음과 같습니다.

Sunrise (2) #4k #googleimages #wallpaper.jpg

이 목표를 어떻게 달성할 수 있나요?파일을 전달하는 방법도 모르겠습니다.이름를 해당 내용 대신에 다음과 같은 명령으로 변환한 sort다음 해당 출력을 mv.

답변1

#!/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

답변2

renamePerl 기반 ( prename일부 시스템)을 사용하는 경우 Perl을 사용하여 태그를 분할+정렬할 수 있습니다. 예를 들어, 주어진

$ ls *.jpg
Sunrise (2) #wallpaper #4k #googleimages.jpg

그런 다음 (접미사를 제거하고 교체하기 위해 추악한 논쟁을 벌입니다 .jpg)

$ rename -v 'my @F = split / #/, substr($_,0,-4); $_ = (join " #", shift @F, sort @F) . ".jpg"' *.jpg
Sunrise (2) #wallpaper #4k #googleimages.jpg renamed as Sunrise (2) #4k #googleimages #wallpaper.jpg

조사하다

$ ls *.jpg
Sunrise (2) #4k #googleimages #wallpaper.jpg

아마도 개선의 여지가 많이 있을 것입니다. 하지만 이것이 여러분에게 몇 가지 아이디어를 제공해주기를 바랍니다.

답변3

그리고 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)숨겨진 파일(또는 파일)도 처리하거나 D숨겨진 디렉터리에 있는 파일을 처리하려면 glob 한정자를 추가하세요.

답변4

솔직히 말해서 이것은 Bash에게는 너무 복잡해 보입니다. 불가능하지는 않지만 내 생각에는 "실제" 프로그래밍용으로 설계된 언어를 사용하는 것이 더 좋습니다. Bash 솔루션은 유지 관리가 불가능할 수 있습니다. (Bash 전용 솔루션을 모욕하려는 것이 아니라 이름 바꾸기 마법이 실제로 꽤 마법적이라고 생각합니다)

즉, 이것이 Ruby의 솔루션입니다. Ruby가 설치되어 있으면 파일에 기록한 다음 셸에서 파일을 실행할 수 있습니다.

#!/usr/bin/env ruby
Dir.glob('*.jpg').each do |filename|
    # `name` contains the name of the file, without the tags. `tags` is an array
    # of all tags of the file.
    name, *tags = filename.split(' #')
    # if there aren't any tags, just skip the file.
    if tags.empty?
        next
    end
    # remove the trailing '.jpg' and sort all the tags
    tags.last.gsub!(/\.jpg$/,'')
    tags.sort!
    tags = [name] + tags
    # finally, move the file to the correct location with sorted tags.
    File.rename filename, "#{tags.join(' #')}.jpg"
end

스크립트를 실행하려면 이미지와 동일한 디렉터리에 스크립트를 배치하면 됩니다. 이 솔루션은 어리석은 이미지 이름과 태그에 대해 상당히 탄력적이어야 하며 C#문제를 일으키지 않아야 합니다. 즉, 스크립트를 실행하기 전에 반드시 백업을 만드십시오. 이동 작업은 과 관련될 수 있습니다 rm.

관련 정보