Home > Back-end >  move files based on a keyword/separator to a terget folder of that keyword name (create folder if it
move files based on a keyword/separator to a terget folder of that keyword name (create folder if it

Time:09-30

I have multiple files of various extensions like .csv, .pdf, .xml, .txt, .xlsx and so on. Files are either in a format of abc.xyz.com_xxxx.extension or abc_xxxx.extension. (The file names are basically subdomains.domain_sometool.extension. for eg a nikto scan on a url like register.google.com would give me file name such as register.google.com_nikto.txt/csv/xml or it migth be saved as register_nikto.txt/csv/xml)

What i want to do is move each file into its subdomain directory. for eg abc.xyz goes into a folder named abc, pqr.abc goes into a folder named pqr. If a subdirectory exists then it should be moved into that and if it does not exist a new directory shall be created for that subdomain.

Solutions in python, bash or powershell will be appreciated.

I have the following code from one of the other stack overflow questions. I would like a code which does similar thing for all types of extensions at once.

for i in *_*.txt; do 
    fp="${i/_?*/}"
    mkdir "$fp" 2>/dev/null # ignore errors else this will complain for 2nd etc files
    mv "$i" "$fp"
done
# do remaining .txt files, with no "_"
for i in *.txt; do 
    fp="${i/.txt/}"
    mkdir "$fp" 2>/dev/null # ignore errors else this will complain for 2nd etc files
    mv "$i" "$fp"
done

CodePudding user response:

In PowerShell you could do something like this:

# define extensions to process
$extensions = -split '.csv .pdf .xlsx .xml .txt .otherExtesions .etcetera'

# switch location to relevant folder
Set-Location path\to\folder\with\files

# iterate over all files in folder, filter for extensions
Get-ChildItem -File -Filter *_*.* |Where-Object Extension -in $extensions |ForEach-Object {
  # grab the first DNS label from the file name
  $label = $_.Name -split '[._]' |Select -First 1

  # test if target folder exists, otherwise create it
  if(-not(Test-Path -LiteralPath $label)){
    New-Item -Name $label -ItemType Directory |Out-Null
  }

  # move file to target folder
  $_ |Move-Item -Destination $label
}

CodePudding user response:

If I understand correctly, the target subfolder name is derived from the first part of the file's name, separated from the rest of the name by either a dot (.) or an underscore (_).

In PowerShell you could do this:

$sourcePath      = 'X:\TheSourceDirectory'
$destinationPath = 'Y:\RootPathForTheSubDirectories'
# get a list of all files, except '.ps1' script files
$files = Get-ChildItem -Path $sourcePath -File | Where-Object {$_.Extension -ne '.ps1'}
foreach ($file in $files) {
    $targetFolder = Join-Path -Path $destinationPath -ChildPath (($file.BaseName -split '[._]')[0])
    if (-not (Test-Path -Path $targetFolder -PathType Container)) {
        $null = New-Item -Path $targetFolder -ItemType Directory
    }
    $file | Move-Item -Destination $targetFolder
}

CodePudding user response:

Using bash:

#!/bin/bash

for file in *.*_*.*; do
    [[ -f $file ]] || continue
    dir=${file%%.*}
    mkdir -p "$dir" && mv "$file" "$dir"
done
  • Related