Dodaj nazwy folderów do nazwy pliku i spłaszcz strukturę pliku

5

Mam na przykład kilka folderów o różnych nazwach

2013-02   Snow and birds
    PICT0001.jpg
    PICT0002.jpg
2013-06   Bicycle trip
    edited_panorama.jpg
    From phone
        DCIM0001.jpg
        DCIM0002.jpg
        DCIM0003.jpg
    From camera
        DSLR
            PICT0001.raw
            PICT0002.raw
        Compact
            S0000001.jpg           

Jak widać, ogólna struktura jest zmiennym poziomem zagnieżdżonych podfolderów zawierających obrazy. Chcę spłaszczyć strukturę, dodając nazwę każdego poziomu podfolderów do nazwy pliku, tak jak poniżej:

2013-02   Snow and birds_PICT0001.jpg
2013-02   Snow and birds_PICT0002.jpg
2013-06   Bicycle trip_edited_panorama.jpg
2013-06   Bicycle trip_From phone_DCIM0001.jpg
2013-06   Bicycle trip_From phone_DCIM0002.jpg
2013-06   Bicycle trip_From phone_DCIM0003.jpg
2013-06   Bicycle trip_From camera_DSLR_PICT0001.raw
2013-06   Bicycle trip_From camera_DSLR_PICT0002.raw
2013-06   Bicycle trip_From camera_Compact_S0000001.jpg

Jak można to osiągnąć za pomocą skryptu terminalowego lub innego skryptu? Znalazłem podobne rozwiązania, ale wszystkie wydają się polegać na stałym poziomie podfolderów, podczas gdy moja struktura folderów jest różna.

Magnus W.
źródło

Odpowiedzi:

5

Podstępny, szczególnie jeśli chcesz zachować wszystkie spacje itp. Uruchom następujące polecenie w głównym katalogu (tym, który zawiera 2013-02 Snow and birdsitp.):

find . -type f -exec sh -c 'for f do x=${f#./}; echo mv "$x" "${x////_}"; done' {} +

Przypisanie do xpozbywa czołowych ./od findtego, ${x////_}zastępuje wszystkie (pozostałe) wystąpień /z _.

Ponadto zabezpieczyłem rzeczywisty mvza pomocą echo, abyś mógł najpierw sprawdzić, czy polecenia wyglądają dobrze. Uruchom komendę ponownie bez echozmiany nazwy / przenoszenia plików.

nohillside
źródło
Działa świetnie! Chociaż brakowało 3 plików z 8300 z jakiegoś niewytłumaczalnego powodu. Na szczęście po przeniesieniu plików rozszerzyłem wszystkie foldery i podfoldery! Wszystkie 3 pliki zostały zagnieżdżone tylko na głębokości 1 poziomu i w folderach, w których wcześniej były inne pliki o podobnych nazwach (PICT0001.JPG itp.).
Magnus W
0

Na potrzeby tego skryptu miałem wszystkie twoje foldery w folderze o nazwie „Filez” na moim pulpicie. Ten skrypt rozpoczyna się od okna dialogowego „wybierz folder”, aby wybrać folder zawierający folder, w którym znajdują się foldery „2013-06 Wycieczka rowerowa” i „2013-02 Śnieg i ptaki”. Spowoduje to zwrócenie wszystkich pojedynczych plików we wszystkich folderach i podfolderach, których nazwy chcesz zmienić.

set mainFolder to choose folder
set posixPathOfMainFolder to POSIX path of mainFolder
tell application "Finder"
    set theNames to files of entire contents of mainFolder as alias list
end tell
set newFileNames to {}
repeat with aFile in theNames
    set text item delimiters to {posixPathOfMainFolder, "/"}
    set aFile to POSIX path of aFile
    set tempName to text items -1 thru 2 of aFile
    set text item delimiters to "_"
    set end of newFileNames to tempName as text
    set text item delimiters to ""
    tell application "Finder"
        set the name of (aFile as POSIX file as alias) to last item of newFileNames as text
    end tell
end repeat
tell application "Finder"
    set theNames to files of entire contents of mainFolder as alias list
    move theNames to mainFolder
    delete folders of mainFolder
end tell

wprowadź opis zdjęcia tutaj

wch1zpink
źródło
0

Powyższa odpowiedź @nohillside jest naprawdę świetna. Jedyny problem polega na tym, że nie uwzględnia plików ze spacjami. Spowoduje to, że niektóre polecenia przestaną działać.

Dlatego zamieszczam odpowiedź, która również by to poparła.

To po prostu echosię do mvpoleceń:

find . -type f -exec sh -c 'for f do x=${f#./}; y="${x// /_}"; echo "mv ${x// /\ } ${y////-}"; done' {} +

To po prostu echosię do mvpolecenia w swojej kartonowe bezpośrednio:

find . -type f -exec sh -c 'for f do x=${f#./}; y="${x// /_}"; echo "mv ${x// /\ } ${y////-}"; done' {} + | pbcopy

[Ostrożnie] Spowoduje to natychmiastowe uruchomienie mvpoleceń:

find . -type f -exec sh -c 'for f do x=${f#./}; y="${x// /_}"; eval "mv ${x// /\ } ${y////-}"; done' {} +
xemacobra
źródło
Teraz jestem ciekawy :-) Który konkretny scenariusz ze spacjami powoduje, że mój fragment kodu nie działa?
nohillside
Tylko jeśli nazwa pliku zawiera spacje. Nie usuwa znaków spacji, echowięc ma bezpośrednie kopiowanie i wklejanie, działa dla większości plików, z wyjątkiem tych, które wyrzucają błąd wyjaśniający użycie mvusage: mv [-f | -i | -n] [-v] source target
xemacobra
3
Chodzi o to, aby nie kopiować / wklejać wyniku, ale usunąć echo, gdy wynik wygląda dobrze. Ale jak zwykle jest wiele sposobów :-)
nohillside