2015-08-20 3 views
10

मैं एक बैच फ़ाइल में उपयोग करने के लिए एक अस्थायी फ़ाइल का पथ बनाने की कोशिश कर रहा हूं।बाहरी उपकरण के बिना कमांड प्रॉम्प्ट में एक अद्वितीय अस्थायी फ़ाइल पथ कैसे बनाएँ?

वर्तमान उपयोगकर्ता के लिए अस्थायी निर्देशिका प्राप्त करने के लिए पर्यावरण चर %TEMP% और %TMP% हैं। लेकिन एक फ़ाइल नाम कैसे बनाया जाए जो निश्चित रूप से अभी तक अस्तित्व में नहीं है?

बेशक मैं अंतर्निहित वैरिएबल %RANDOM% और बनाने bat~%RANDOM%.tmp की तरह कुछ का उपयोग कर सकते हैं, लेकिन इस विधि पहले यह सुनिश्चित करता है नहीं वर्तमान में उस फ़ाइल गैर-मौजूद है (या कि यह संयोग अन्य अनुप्रयोग द्वारा बनाया जाएगा, मैंने पहले इसे डिस्क पर बनाएं और इसे लिखें) - हालांकि यह सब बहुत ही असंभव है।

मैं जानता हूँ कि मैं सिर्फ भी जोड़कर %DATE%/%TIME% द्वारा इस तरह के टकराव की संभावना को कम कर सकता है, या बस कई %RANDOM% उदाहरणों को जोड़कर, लेकिन यह नहीं है कि मैं क्या चाहते हैं ...

नोट: के अनुसार this post, .NET (Path.GetTempFileName()) में एक विधि है जो वास्तव में मैं जो पूछ रहा हूं (गलत प्रोग्रामिंग भाषा के अलावा)।

उत्तर

6

अगले कोड स्निपेट का प्रयास करें:

@echo off 
setlocal EnableExtensions 

rem get unique file name 
:uniqLoop 
set "uniqueFileName=%tmp%\bat~%RANDOM%.tmp" 
if exist "%uniqueFileName%" goto :uniqLoop 

या प्रक्रियाओं

  • :uniqGet बनाने: (आपके मामले में bat~%RANDOM%.tmp) एक फिक्स फ़ाइल नाम टेम्पलेट की एक फ़ाइल बनाने के;
  • :uniqGetByMask: एक परिवर्तनीय फ़ाइल नाम टेम्पलेट की एक फ़ाइल बनाएं। नोट प्रक्रिया प्रक्रिया में %random% संदर्भ के चौथे प्रतिशत संकेत: prefix%%%%random%%%%suffix.ext। प्रक्रिया के अंदर call set "_uniqueFileName=%~2" में advanced usage: CALLing internal commands भी ध्यान दें।

कोड इस प्रकार हो सकता है:

@ECHO OFF 
SETLOCAL enableextensions 
call :uniqGet uniqueFile1 "%temp%" 
call :uniqGet uniqueFile2 "%tmp%" 
call :uniqGet uniqueFile3 d:\test\afolderpath\withoutspaces 
call :uniqGet uniqueFile4 "d:\test\a folder path\with spaces" 

call :uniqGetByMask uniqueFile7 d:\test\afolder\withoutspaces\prfx%%%%random%%%%sffx.ext 
call :uniqGetByMask uniqueFile8 "d:\test\a folder\with spaces\prfx%%%%random%%%%sffx.ext" 

set uniqueFile 

pause 

goto :continuescript 
rem get unique file name procedure 
rem usage: call :uniqGetByMask VariableName "folderpath\prefix%%%%random%%%%suffix.ext" 
rem parameter #1=variable name where the filename save to 
rem parameter #2=folder\file mask 
:uniqGetByMask 
rem in the next line (optional): create the "%~dp2" folder if does not exist 
md "%~dp2" 2>NUL 
call set "_uniqueFileName=%~2" 
if exist "%_uniqueFileName%" goto :uniqGetByMask 
set "%~1=%_uniqueFileName%" 
rem want to create an empty file? remove the `@rem` word from next line 
@rem type nul > "%_uniqueFileName%" 
exit /B 

goto :continuescript 
@rem get unique file name procedure 
@rem usage: call :uniqGet VariableName folder 
@rem parameter #1=variable name where the filename save to 
@rem parameter #2=folder where the file should be about 
:uniqGet 
@rem in the next line (optional): create the "%~2" folder if does not exist 
md "%~2" 2>NUL 
set "_uniqueFileName=%~2\bat~%RANDOM%.tmp" 
if exist "%_uniqueFileName%" goto :uniqGet 
set "%~1=%_uniqueFileName%" 
@rem want to create empty file? remove the `@rem` word from next line 
@rem type nul > "%_uniqueFileName%" 
exit /B 

:continueScript 

आउटपुट:

==>D:\bat\SO\32107998.bat 
uniqueFile1=D:\tempUser\me\bat~21536.tmp 
uniqueFile2=D:\tempUser\me\bat~15316.tmp 
uniqueFile3=d:\test\afolderpath\withoutspaces\bat~12769.tmp 
uniqueFile4=d:\test\a folder path\with spaces\bat~14000.tmp 
uniqueFile7=d:\test\afolder\withoutspaces\prfx26641sffx.ext 
uniqueFile8=d:\test\a folder\with spaces\prfx30321sffx.ext 
Press any key to continue . . . 
+0

समस्या है, यादृच्छिक%% वर्तमान समय (सेकंड में) से एक समारोह के रूप उत्पन्न होता है, जिसका अर्थ है कि अपने कोड 1 सेकंड के लिए एक पाश में हो जाएगा जब आप एक दूसरी फ़ाइल की जरूरत है। – Sergei

+0

@ सेर्गी नोप। चल रहा है उदा। '%%% echo और> NUL (/ l% g में (1,1,120) @call d: \ bat \ SO \7998.bat) और cmd/V/C" echo! time! "और dir डी: \ test \ afolderpath \ withoutspaces | "फ़ाइल (ओं)" ढूंढें "दिखाता है कि ** सभी **' 720' फ़ाइलें (= 6 * 120) सीसीए 3.5 सेकंड के दौरान बनाई जाती हैं, बार-बार (अब मेरे पास दिए गए टेम्पलेट पैटर्न की सीसीए 1220 फाइलें हैं प्रत्येक परीक्षण निर्देशिका)। Https://ss64.com/nt/syntax-random.html – JosefZ

+0

पढ़ें जब मैं एक ही कमांड को वास्तव में तेज़ी से चला रहा हूं तो मुझे यह http://imgur.com/a/6SVmu – Sergei

1

सबसे पहले, एक अलग फ़ोल्डर का उपयोग कर काफी घुसपैठ अन्य कार्यक्रमों की संभावना कम हो जाएगा। तो अस्थायी फ़ाइल को एक निजी फ़ोल्डर में स्टोर करने दें जो किसी भी नाम प्रतियोगिता को रोकने के लिए वास्तव में लंबा और विशिष्ट है।

नाम उत्पन्न करते समय, आप हमेशा %random% का उपयोग कर सकते हैं और एक ऐसा नाम उत्पन्न करने का प्रयास कर सकते हैं जो मौजूद नहीं है, हालांकि इस ऑपरेशन का जितना अधिक बार उपयोग होता है, उतना अधिक अप्रभावी हो जाता है। यदि आप इस प्रक्रिया का उपयोग हजारों बार करने के लिए करते हैं क्योंकि यादृच्छिक फ़ंक्शन 32000 तक सीमित है (लगभग) आपका प्रोग्राम हमेशा यादृच्छिक प्रयासों को उत्पन्न करेगा।

अगला सबसे अच्छा तरीका एक काउंटर शुरू करना है और जब तक आपके पास एक अप्रयुक्त नाम नहीं है तब तक इसे बढ़ाएं।इस तरह आप गारंटी दे सकते हैं कि अंततः आपके कार्यक्रम को उचित समय में एक नाम मिल जाएगा, फिर भी आपकी फाइलें ढीली होंगी (जो कभी भी अच्छा अनुभव नहीं है)

कुछ लोग क्या करते हैं (और मैं आपकी स्थिति के लिए अनुशंसा करता हूं

@echo off 

:: Set Temp Folder Path 
set "tp=%temp%\Temporary Name Selection Test" 

:: File name will be XXXXXX_YY.txt 
:::: X's are randomly generated 
:::: Y's are the incremented response to existing files 
set x=%random% 
set y=0 
set "filename=Unexpected Error" 

:loop 
set /a y+=1 
set "filename=%tp%\%x%_%y%.txt" 
if exist %filename% goto loop 

:: At this point, filename is all good 
Echo %filename% 
pause 
1

मैं तुम्हें दो तरीकों में से एक सुझाव है: एक विश्वसनीय तरीका (दोनों दुनिया का सबसे अच्छा) का उपयोग करते समय), प्रक्रियाओं के लिए इन गठबंधन प्रभावी रूप से एक नाम का चयन करने में वसा में कटौती करने के लिए है। "तकनीकी दृष्टिकोण" जेस्क्रिप्ट की FileSystemObject.GetTempName विधि का उपयोग करना है। JScript एक प्रोग्रामिंग भाषा है कि आता है सभी विंडोज संस्करणों में XP से पर पहले से इंस्टॉल है, और एक "बैच JScript" संकर स्क्रिप्ट के माध्यम से बैच में इसके उपयोग बहुत सरल है:

@if (@CodeSection == @Batch) @then 

@echo off 
setlocal 
for /F "delims=" %%a in ('CScript //nologo //E:JScript "%~F0"') do set "tempName=%%a" 
echo Temp name: "%tempName%" 
goto :EOF 

@end 

// JScript section 

var fso = new ActiveXObject("Scripting.FileSystemObject"); 
WScript.Stdout.WriteLine(fso.GetTempName()); 

हालांकि, सबसे सरल दृष्टिकोण करने के लिए है एक डेटा फ़ाइल में एक नंबर स्टोर करें और हर बार जब आप एक नया नाम चाहते हैं, तो संख्या प्राप्त करें, इसे बढ़ाएं और उसे उसी फ़ाइल में वापस स्टोर करें। यह "बस" 2147483647 बार के लिए काम करेगा!

rem Get next number 
set /P "nextNum=" < NextNumber.txt 
set /A nextNum+=1 
echo %nextNum% > NextNumber.txt 
set "tempName=File%nextNum%.txt" 
echo Temp name: %tempName% 
संबंधित मुद्दे