ソートを使用してファイル名の単語をアルファベット順にソートしますか?

ソートを使用してファイル名の単語をアルファベット順にソートしますか?

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

関連情報