Saved Bookmarks
| 1. |
Solve : Make Move Merge & Rename files into directories based on file-name / Bash to DOS? |
|
Answer» LINUX BASH SCRIPT Makes directories from a predefined part of the file-name and moves/merges them into their corresponding defined folder. IF the folder and file already exists, it will merge the file into the pre-existing folder and create a incremental numbered tag at the end of filename (c#). No files are over written. INPUT: Filename Pattern Field1 - Field2.ext Field1 - Field2 - Field3.ext Field1 - Field2 - Field3 (tag).ext Field1 - [Field2] - Field3.ext Field1 - [Field2] - Field3 (tag) (tag2).ext Deliminators: dash, square BRACKET (optional) and parenthesis. These are designated and NOT used elsewhere in FIELD names. Field: The field can contain any of the following: alpha-numerics, apostrophe, ampersand and decimal point. No other special or foreign characters. Code: [Select]#!/bin/bash for i in $(ls | sed 's/ /~/g'); do FILENAME=$(echo "$i" | sed 's/~/ /g') if ! [ -d "$FILENAME" ]; then AUTHORNAME=$(echo "$FILENAME" | awk -F"-" '{ print $1 }' | sed -r 's/ +$//g') if ! [ -d "$AUTHORNAME" ]; then mkdir "$AUTHORNAME" fi COUNT=1 EXTENSION=$(echo "$FILENAME" | awk -F. '{ print $NF }') NEWNAME=$(echo "$FILENAME" | sed -r "s/\.$EXTENSION$//g") TEMPNAME=$NEWNAME while [ -e "$AUTHORNAME/$NEWNAME.$EXTENSION" ]; do NEWNAME="$TEMPNAME(C$((COUNT++)))" done mv "$FILENAME" "$AUTHORNAME/$NEWNAME.$EXTENSION" fi done OUTPUT: John Doe/ John Doe - bbb.ext John Doe - aaa - bbb.ext John Doe - aaa- bbb(tag).ext John Doe - [aaa] - bbb.ext John Doe - [aaa] - bbb (tag) (tag2).ext Linux users, this bash script WORKS like a dream. ISSUE: My husband was kind of enough to write this script for me in Bash (Linux). It works great in Linux, but I need Cygwin to run it in Windows and it's SLOW and buggy. Salmon Trout posted this DOS Batch on a similar Topic: Create folders based on part of filename dated June 22, 2012. which does close to what I want, but makes no concession for merging duplicate file names and renaming them. DOS BATCH: Code: [Select]for /f "delims=" %%A in ('dir /b /a-d ^| find /v "%~nx0"') do ( for /f "tokens=1* delims=-" %%B in ("%%A") do ( if not exist "%%B" md "%%B" if not exist "%%B\%%A" move "%%A" "%%B" ) ) I would like help in expanding this DOS batch to include merging and renaming files if they exist -- much like my Bash Script. My programming skills are limited to simple regular expression. Basically, I wish to convert my Bash to DOS. _______________________________________ ______ PC: Running Windows 7 Home Edition 64 bit / 16 GB RamThe task is unclear, to me at least. You wish to move files from somewhere to somewhere else and not overwrite any files. Does it include subdirectories? Give some examples of the source files and the target files, which should clarify the task.The bash script does the following... BEFORE: J.R.R. Tolkien - Lord of the Rings 01 - The Hobbit.pdf J.R.R. Tolkien - Lord of the Rings 02 - Lord of the Rings.txt J.R.R. Tolkien - Beowulf, The Monsters and the Critics (html).rarx William Shakespeare - A Midsummer Nights Dream.epub William Shakespeare - Alls Well That Ends Well.epub William Shakespeare - Twelfth Night.epub William Shakespeare - Venus And Adonis.epub AFTER: J.R.R. Tolkien/ J.R.R. Tolkien - Lord of the Rings 01 - The Hobbit.pdf J.R.R. Tolkien - Lord of the Rings 02 - Lord of the Rings.txt J.R.R. Tolkien - Beowulf, The Monsters and the Critics (html).rar William Shakespeare/ William Shakespeare - A Midsummer Nights Dream.txt William Shakespeare - A Midsummer Nights Dream.epub William Shakespeare - Alls Well That Ends Well (2ed).epub William Shakespeare - Twelfth Night.epub William Shakespeare - Venus And Adonis (c1).epub William Shakespeare - Venus And Adonis (c2).epub William Shakespeare - Venus And Adonis.epub William Shakespeare - Venus And Adonis.jpg In cases where the folder already exists the files are move into the existing folder. In cases filename already exists the files are rename with an incremental tag to avoid conflict. i.e. (c1), (c2)This seems to work Code: [Select]@echo off setlocal EnableDelayedExpansion for /f "delims=" %%A in ('dir /b /a-d') do ( for /f "tokens=1 delims=-" %%B in ("%%A") do ( set b=%%B if not "%0"=="!b:~0,-1!" ( echo %%B if not exist %%B md %%B move "%%A" "!b:~0,-1!\%%A" ) ) ) pause This task is complicated by the need to rename and add a suffix - and that suffix has to be removed to compare further similar files. However this seems to work here in my test. Try it on copies of your files first. The source filespec can simply be *.* and the target is where your folders are to be CREATED and could be simply books to move into a books folder in the current directory. Code: [Select]@echo off set "source=d:\abc\*.*" set "target=d:\abc\books" md "%target%" 2>nul FOR %%a in ("%source%") do call :next "%%a" pause goto :eof :next for /f "delims=-" %%b in ("%~n1") do set "folder=%%b" if "%folder%"=="%~n1" goto :EOF if "%folder:~-1%"==" " set "folder=%folder:~0,-1%" md "%target%\%folder%" 2>nul set c=-1 set "name=%~n1" :: remove existing " (cNNN)" echo "%name%|" |findstr /r /c:" (c[0-9]*)|">nul && call :remove :loop set /a c=c+1 set num= (c%c%) if %c% EQU 0 (set num=) if exist "%target%\%folder%\%name%%num%%~x1" goto :loop echo processing %1 MOVE /-Y "%~1" "%target%\%folder%\%name%%num%%~x1" >nul goto :EOF :: Search and Replace - strings :remove call :Search_and_replace "%name%" for /f "delims=" %%c in ('cscript /nologo _.vbs') do set "name=%%c" ) del _.vbs goto :EOF :Search_and_replace set s=regex.replace("%~1","$1") >_.vbs echo set regex=new regexp >>_.vbs echo regex.global=True >>_.vbs echo regEx.IgnoreCase=True >>_.vbs echo regex.pattern="(.*) \(c[0-9]*\)" >>_.vbs echo wscript.stdOut.write %s% First, a 'thank you' both, your help is greatly appreciated. I pressed your buttons. Foxidrive's batch works like a charm. I even tweaked a copy so it can run on the root directory of the batch file. I now have a choice and flexibility; one for my LIBRARY folder with targetand source set and one portable for drag-n-drop. Foxidrive's Tweaked Version: No target or Source: runs on root of batch file. Code: [Select]@echo off FOR %%a in ("*.*") do call :next "%%a" pause goto :eof :next for /f "delims=-" %%b in ("%~n1") do set "folder=%%b" if "%folder%"=="%~n1" goto :EOF if "%folder:~-1%"==" " set "folder=%folder:~0,-1%" md "%folder%" 2>nul set c=-1 set "name=%~n1" :: remove existing " (cNNN)" echo "%name%|" |findstr /r /c:" (c[0-9]*)|">nul && call :remove :loop set /a c=c+1 set num= (c%c%) if %c% EQU 0 (set num=) if exist "%folder%\%name%%num%%~x1" goto :loop echo processing %1 MOVE /-Y "%~1" "%folder%\%name%%num%%~x1" >nul goto :EOF :: Search and Replace - strings :remove call :Search_and_replace "%name%" for /f "delims=" %%c in ('cscript /nologo _.vbs') do set "name=%%c" ) del _.vbs goto :EOF :Search_and_replace set s=regex.replace("%~1","$1") >_.vbs echo set regex=new regexp >>_.vbs echo regex.global=True >>_.vbs echo regEx.IgnoreCase=True >>_.vbs echo regex.pattern="(.*) \(c[0-9]*\)" >>_.vbs echo wscript.stdOut.write %s% |
|