Úlohu řeším nejspíše dosti neefektivním způsobem. V první části skriptu vyhledám soubory v testovacích složkách, vypočítám k nim kontrolní součty a vyberu ty soubory, které mají stejné jméno, ale liší se obsahem. V druhé části už jen formátuji, přidám čas poslední modifikace a vyberu nejnovější. Tento postup nemá rád soubory s bílými znaky, což ovšem lze vyřešit separátně pomocí přejmenování souborů, resp. adresářů.
$ find -name "* *" -type f | rename 's/ /_/g' #přejmenuje soubory, místo mezer dá podtržítka
$ find -name "* *" -type d | rename 's/ /_/g' #přejmenuje adresáře, místo mezer dá podtržítka
Začnu vyhledáním pomocí find
ve dvou testovacích složkách ~/test1/ a ~/test1/, zajímají mě pouze soubory -type f
. Ty pošlu rourou přes xargs
do md5sum
, který vypočítá k souborům jejich kontrolní součty.
$ find ~/test1/ ~/test2/ -type f | xargs md5sum
Teď následuje procedura, která kontroluje výskyt jmen (předpokládám, že jména neobsahují /, pokud ano, lze to vyřešit podobně jako s mezerami). V awk
nastavím oddělovač / pomocí -F/
, díky čemuž je jméno souboru vždy na pozici $NF
. Dále kontroluji, jestli ve vektoru jmena[]
na pozici, kterou zrovna čtu už něco je. Pokud ano, zkontroluji jestli se liší od ostatních a případně zvýším počet výskytů. Pak do vektoru připíši čtený řádek a zapamatuji si kontrolní sumu, pro případ porovnání. Když awk skončí se čtením řádků, vypíše sumy a cesty ke vybraným souborům.
$ find ~/test1/ ~/test2/ -type f | xargs md5sum |
awk -F/ '{if(jmena[$NF]) {if(md5[$NF]!=$1) {vyskyty[$NF]++}}
jmena[$NF]=jmena[$NF] $0"\n"
md5[$NF]=$1 }
END { for( d in vyskyty ) {printf jmena[d]}}'
Nyní už je postup docela přímočarý, pomocí cut -c
oříznu sumy na začátku řádku, jména souborů pošlu rourou do podrobného ls -l
, kde si navolím long-iso
formát času. Opět pomocí cut -c
oříznu nezajímavé položky a už jednou použitým trikem s awk -F/
vyrobím jména souborů kvůli třídění. Soubory roztřídím pomocí sort -k4 -k1r -k2r
, kde první volba znamená primární třídění podle jména souboru a další dvě jsou podle datumu a času obráceně, tak aby nové soubory byly navrchu. Na závěr pomocí uniq -f 3
vyberu první řádky s unikátním jménem ve třetím sloupci. Celý skript níže:
$ find ~/test1/ ~/test2/ -type f | xargs md5sum |
awk -F/ '{if(jmena[$NF]) {if(md5[$NF]!=$1) {vyskyty[$NF]++}}
jmena[$NF]=jmena[$NF] $0"\n"
md5[$NF]=$1 }
END { for( d in vyskyty ) {printf jmena[d]}}' |
cut -c35- | xargs ls -l --time-style=long-iso | cut -c28- | awk -F/ '{print($0" "$NF)}' | sort -k4 -k1r -k2r | uniq -f 3