Search code examples
pythonpowershellfile-renamebatch-rename

Embedding file paths to names


I have a similar issue: I want to batch-rename files like:

c:>/folder/path_a/to/my_first_file.txt
c:>/folder/path_b/to/my_2_nd_file.txt
c:>/folder/path_c/to/my_bla_bla.txt
c:>/folder/path_d/to/pippo.txt
c:>/folder/path_d/to/pluto.txt
c:>/folder/path_d/to/my_bla_bla.txt

and I'd would rename them as:

c:>/folder/path_a-to_my_first_file.txt
c:>/folder/path_b-to-my_2_nd_file.txt
c:>/folder/path_c-to-my_bla_bla.txt
c:>/folder/path_d-to-pippo.txt
c:>/folder/path_d-to-pluto.txt
c:>/folder/path_d-to-my_bla_bla.txt

'embedding' part of the path to the filename

Can someone help me (I'm using Windows)?

Found this but I don't know how to tell PS 'grab only subdirectorys name'

EDIT: On python I'll have done sometng like this (sorry if code doesn't work but here I havn't python):

for dirname, _, fnames in os.walk('.'):
    first=dirname.replace('\','-')
    for fname in fnames:
        name="{}-{}".format(first,fname)
        os.rename("{}\{}".format(dirname,fname),"{}"name)

for for dirname,_,fname in os.walk('.'):
    os.remove(dirname)

================= Update ===================

As dealing with powershell was becaming a time-consuming issue, i put my data on a usb drive and used the following python script on another machine to do the job: (the script also changes the filename to remove an previous '.c' extention that was enbedded in flenames)

from os import rename, walk, chdir
EXT = '.c'
PATH = 'folder'    

chdir(PATH)
for cart, _, files in walk("."):
        for i in files:
                if os.path.isfile("{}/{}".format(cart,i)):
                        if EXT in i:
                                nn = i.replace(EXT,'') #removes inner extension
                                rename('{}/{}'.format(cart,i),'{}-{}'.format(cart,nn)) #changes the path

Solution

  • Flattening/collapsing a directory tree isn't just renaming but moving files and afterwards deleting (empty) dirs.

    ## Q:\Test\2017\09\27\SO_46452350.ps1
    $Base = 'C:\folder\'
    Set-Location $Base
    Get-ChildItem -Dir | ForEach-Object {
        Get-ChildItem -Path $_ -File -Recurse |
            Move-Item -Destination {Join-Path $Base ($_.FullName.Replace($Base,'').Replace('\','_'))} 
        $_ | Remove-Item -Recurse
    }
    

    Sample tree:

    > tree /F
    C:.
    └───folder
        ├───path_a
        │   └───to
        │           my_first_file.txt
        │
        ├───path_b
        │   └───to
        │           my_2_nd_file.txt
        │
        ├───path_c
        │   └───to
        │           my_bla_bla.txt
        │
        └───path_d
            └───to
                    my_bla_bla.txt
                    pippo.txt
                    pluto.txt
    

    After running script:

    > tree /F
    C:.
    │
    └───folder
            path_a_to_my_first_file.txt
            path_b_to_my_2_nd_file.txt
            path_c_to_my_bla_bla.txt
            path_d_to_my_bla_bla.txt
            path_d_to_pippo.txt
            path_d_to_pluto.txt