Ridenominazione di file con file non ASCII per aggiungere il proprio datetime in ASCII
L'ambiente multilingue e il nostro archivio di file su Linux, ovviamente, consentono tutti quei caratteri internazionali (asiatici) nei nomi dei file. Ma questo sta causando problemi di sincronizzazione con altri sistemi perché tutti i caratteri internazionali vengono trattati dagli altri sistemi come ??? o qualcosa del genere, e non sono più nomi di file univoci per quei sistemi (il colpevole è MS Onedrive / Sharepoint con cui stiamo cercando di sincronizzarci) - due file nella stessa directory con nomi diversi (caratteri asiatici) ma con lo stesso numero di i caratteri vengono trattati come aventi nomi di file identici, sfortunatamente, e otteniamo un errore di copia. Sembra che non ci siano soluzioni alternative ad eccezione della ridenominazione dei file.
Voglio semplicemente aggiungere i datetimes dei file in ASCII ai loro nomi di file e questo dovrebbe risolverlo.
Questo comando funziona magnificamente per trovare tutti i file che sono 'problematici' per me, per così dire: individua tutti i caratteri non ASCII nei nomi di file e cartelle in / path / to / files / e tutte le sottocartelle:
find /path/to/files/ | grep -P "[\x80-\xFF]"
Quello che devo fare con quei file è aggiungere il nome del file di base con il datetime del file in ASCII (lasciando solo l'estensione del file, così com'è).
Praticamente qualsiasi data e ora funzionerebbe, sia la nascita, la modifica, la modifica della data come da stat. Le informazioni restituite da questi funzionerebbero, ad esempio:
stat -c '%y' filename
date -r filename
Non riesco a capire come aggiungere automaticamente questi datetimes per i file ai nomi file di base dei file elencati da quel primo comando find.
Risposte
Con 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
Ho sentito che alcuni sistemi operativi Microsoft hanno problemi con i nomi di file che contengono :
caratteri, quindi potrebbe essere necessario adattare il formato del timestamp (qui in formato standard internazionale con precisione al millisecondo 2020-08-23T08:14:38.318+0100
). Queste sono le strftime()
direttive di formattazione standard , ad eccezione della %<precision>.
parte del secondo secondo che è -specific zsh
(non c'è equivalente in strftime()
).