非ASCIIファイルでファイルの名前を変更して、ASCIIで独自の日時を追加する

Aug 23 2020

もちろん、多言語環境とLinux上のファイルストレージでは、ファイル名にこれらすべての国際(アジア)文字を使用できます。しかし、これは他のシステムとの同期に問題を引き起こしています。これは、国際文字がすべて他のシステムによって???として扱われるためです。または何か、そしてそれらはもはやそれらのシステムに固有のファイル名ではありません(原因は同期しようとしているMS Onedrive / SharePointです)-同じディレクトリ内の異なる名前(アジアの文字)で同じ数の2つのファイル残念ながら、文字は同じファイル名を持つものとして扱われ、コピーエラーが発生します。ファイルの名前を変更する以外に回避策はないようです。

ファイル自体の日時をASCIIでファイル名に追加したいのですが、これで解決するはずです。

このコマンドは、いわば「問題のある」すべてのファイルを見つけるために美しく機能します。つまり、ファイル内のすべての非ASCII文字と、/ path / to / files /およびすべてのサブフォルダー内のフォルダー名を見つけます。

find /path/to/files/ | grep -P "[\x80-\xFF]"

これらのファイルで行う必要があるのは、ベースファイル名にファイル自体の日時をASCIIで追加することです(ファイル拡張子はそのままにします)。

統計に従って、誕生、変更、日付の変更など、ほぼすべての日時が機能します。これらによって返される情報は、たとえば次のように機能します。

stat -c '%y' filename

date -r filename

その最初の検索コマンドでリストされたファイルのベースファイル名に、ファイルのこれらの日時を自動的に追加する方法がわかりません。

回答

2 StéphaneChazelas Aug 23 2020 at 07:17

zsh

#! /bin/zsh -
zmodload zsh/stat
zmodload zsh/files # for its builtin mv to speed things up.
set +o multibyte -o extendedglob

# comment-out the line below once you're satisfied it does what you want.
mv() { printf 'Would rename %s to %s\n' ${(q+)2} ${(q+)3}; }

ts_format='-%FT%T.%3.%z'

# we build a $ts_pattern to be able to identify files that already have # had a timestamp appended, by obtaining a sample timestamp for the / # directory, and replacing all digits in it with [0-9]. That assumes you # don't use wildcard characters nor day/month/timezone names, am/pm in your # $ts_format.
stat -F $ts_format -A ts_sample +mtime / ts_pattern=${ts_sample//[0-9]/[0-9]}

for file in **/(*[$'\x80'-$'\xff']*~*$~ts_pattern(.*|))(DNod); do stat -LF $ts_format -A ts +mtime -- $file || continue case $file:t in
    (?*.*) mv -- $file $file:r$ts.$file:e;; # insert ts before extension
    (*)    mv -- $file $file$ts;;
  esac
done

一部のMicrosoftOSでは、:文字を含むファイル名に問題があるため、タイムスタンプ形式(ここではミリ秒精度の国際標準形式2020-08-23T08:14:38.318+0100)を調整する必要があると聞きました。これは、-固有のサブセカンド部分をstrftime()除いて、標準のフォーマットディレクティブ%<precision>.ですzsh(に同等のものはありませんstrftime())。