蝙蝠解析文件夹的奇怪回复

时间:2014-01-03 15:17:55

标签: batch-file

我有一个脚本 1-计算文件夹中文件+文件夹的数量(作为参数传递) 2-如果其中只有一个文件,则将该文件移动到父文件夹,然后删除初始文件夹

ex start:
folder-folder1-file1
      -folder2-file21
              -file22

final:
folder-file1
folder-folder2-file21 (untouched there is more than one unique file)
              -file22 (untouched there is more than one unique file)

代码:

@echo off 
setLocal ENABLEDELAYEDEXPANSION
SET source_file=%1
echo source file = %source_file%
set N=
REM ok
for /f "tokens=* delims= " %%a in ('dir/b %source_file%') do (
set /a N+=1
echo DETECTED:%%a
REM echo
)
 echo Number DETECTED:!N!


if %N% gtr 1 goto end
:Moving
echo.
echo  --------------------MOVING----------------------
REM unable to get the result of the precedent for loop
for /f "tokens=* delims= " %%a in ('dir/b %source_file%') do (
rem ok
echo native:%%a
rem STRANGE the last folder is missing !!!!!!!!!!!!!!!!!
echo fully qualified path name:%%~fa
rem STRANGE the last folder is missing !!!!!!!!!!!!!!!!!
echo expands to a drive letter and path only:%%~dpa
rem ok
echo expands to a file extension only:%%~xa
 if not "%%~xa" == "" (
    echo this is a file!!!
    REM MOVE "%%~fa" ..
    REM RD "%%~dpa"
)   else (
echo this is a folder ...going out

)
)
goto end2
:end
echo nothing to do...going out
:end2
pause

第一部分运作良好>如果有一个元素>前进  第二部分给出了奇怪的结果(文件夹在桌面上): dos窗口

source file = C:\Users\ap\Desktop\Folder                         <OK
DETECTED:file1.txt                                               <OK
Number DETECTED:1                                                <ok

 --------------------MOVING----------------------
native:file1.txt
fully qualified path name:C:\Users\ap\Desktop\file1.txt          <STRANGE does NOT exist
expands to a drive letter and path only:C:\Users\ap\Desktop\     <STRANGE "Folder" MISSING
expands to a file extension only:.txt                            <OK
this is a file                                                   <OK

所以移动itsefl不起作用! 为什么? 我错过了什么?

4 个答案:

答案 0 :(得分:0)

你可以试试这个:

@ECHO OFF &SETLOCAL
rem count the files
for /r %%a in (*) do set /a fcnt+=1
echo %fcnt% files

rem count the directories
for /d /r %%a in (*) do set /a dcnt+=1
echo %dcnt% directories

rem move the orphan file
for /d /r %%a in (*) do (
    set "f1=true"
    set "f2=true"
    for /f "delims=:" %%b in ('dir /b /a-d "%%~a\*" 2^>nul ^|findstr /n $') do (
        set "f1="
        if %%b gtr 1 set "f2="
    )
    if not defined f1 if defined f2 (
        for %%b in ("%%~dpa.") do (
            echo move "%%~a\*" "%%~fb"
            rd "%%~a" 2>nul
        )
    )
)

答案 1 :(得分:0)

计算目录数量并显示它。 计算文件数量并显示它。 计算每个文件夹中的文件和目录数(不包括父项和自身) 如果文件数为1且没有目录,则移动文件并删除目录。

更新代码以运行序列,就像要做的那样。这是递归移动文件的最简单方法,但可能不是最佳方法。 我希望在名称中不会有带转义符号的文件夹。

@echo off
setlocal enabledelayedexpansion

:loop
set totalMoves=0
set /p "aaa=Number of directories: " < nul
dir /B /S /AD | find /C /V ""
set /p "aaa=Number of files: " < nul
dir /B /S /A-D | find /C /V ""

for /F "tokens=*" %%a in ('dir /B /S /AD') do (
    for /f %%x in ('dir "%%a" ^| find /V ":" ^| find "File(s)"2^>nul') do set nf=%%x
    for /f %%x in ('dir "%%a" ^| find /V ":" ^| find "Dir(s)" 2^>nul') do set /a nd=%%x-2
    if !nf!==1 if !nd!==0 (
        set /a totalMoves+=1
        echo Folder to execute" "%%a"
        move "%%a\*" "%%a\..\"
        rmdir "%%a"
    )
)

if !totalMoves! NEQ 0 goto :loop

答案 2 :(得分:0)

您的问题似乎是批次只知道文件名。然后假定文件(实际位于目标目录中)位于当前目录中。

如果你要PUSHD目标目录(我稍后会假设你知道它POPD,但是有提醒......)那么问题就会消失。


嗯 - 问题是关于"strange reply for a bat parsing folders"所以我相信已经解释过了。现在我们还有一个问题"How do I move a single file from a directory to its directory to its parent and then delete the directory if it contains only one file"

@ECHO OFF
SETLOCAL
SET "moveme="
PUSHD "%~1"
FOR /f %%x IN ('dir /b "%~1" 2^>nul') DO (
 IF DEFINED moveme ECHO Too many files&pause&GOTO :eof
 SET moveme=%%x
)
IF DEFINED moveme IF NOT EXIST "%~1\%moveme%\" ECHO MOVE "%~1\*" ..
pause

应该执行该任务。 PAUSE是允许查看结果,并且应在验证后删除。 echo用于测试,需要删除以激活移动和目录删除。

moveme在开始时设置为空。如果目标中有一个条目,则将其设置为该条目的名称。如果遇到第二个条目,则将定义moveme,因此批处理退出。

如果只有一个条目且该条目不是目录名,则所需的说明为echo

答案 3 :(得分:0)

@echo off
    rem Prepare environment
    setlocal enableextensions disabledelayedexpansion

    rem 1|0 to indicate that folders are not treated as files
    rem When it is 0, it indicated that there is no difference between one folder
    rem containing only one file, and one folder containing only one folder
    rem When it is 1, folders are not considered as files and simplify rules does not apply to them
    set "skipFolders=1"

    rem Determine from where to start
    set "folder=%~1"
    if not defined folder set "folder=%cd%"

    rem Begin the work. 

    rem Will hold a lock on batch file to avoid undesired move/deletion of
    rem batch file or folders containing it
    < "%~f0" (

        rem Retrieve the recursive list of folders  in reverse order to work from bottom to top
        for /f "tokens=*" %%f in ('dir /ad /s /b "%folder%" 2^>nul ^| sort /r ') do (

            rem Determine the contents of the folder counting files and folders
            rem To exclude folders in the final decision, add skipFolders, so the count will
            rem not be 1 in the case of only one folder and no files
            set "contents=0"
            for /d %%c in ("%%~ff\*") do set /a "contents+=1+%skipFolders%"
            for    %%c in ("%%~ff\*") do set /a "contents+=1"

            rem Test if there is only one element in folder, so "simplification" is required
            setlocal enabledelayedexpansion
            if !contents! equ 1 (
                endlocal

                rem Let's try to remove this level if there is no name collision on new parent
                for /f "tokens=*" %%e in ('dir /b "%%f\*" 2^>nul') do if not exist "%%~dpf\%%~nxe" (

                    rem Move selected element one level up and delete extra folder
                    move /y "%%~ff\%%~nxe" "%%~dpf" >nul 2>nul 
                    if not errorlevel 1 rd "%%~ff" >nul 2>nul || break
                    if not errorlevel 1 echo ... fold on "%%f"
                )
            ) else (
                endlocal
            )
        )
    )

    endlocal