Page 1 of 2

Determine Yes/No/All string for current locale

Posted: 19 Feb 2014 18:54
by dbenham
I would like to determine the Yes / No / and All strings for the current locale in a locale independent manner. This stems from my batchTee.bat script that needs to know the Yes string to be able to cleanly abort a script after Ctrl-C. Thanks jeb for the excellent suggestion.

I decided to generalize the problem to compute all three values.

I believe the following script does the job, but I only have an English machine to test.

Can people with non-English machines please test and report for which language(s) it works or fails? Or if there is a better way, let me know?

Code: Select all

@echo off
setlocal
set "yes="
copy /y nul test.tmp >nul
for /f "tokens=2-4 delims=(/)" %%A in (
  '^<nul copy /-y nul test.tmp'
) do if not defined yes (
  set "yes=%%A"
  set "no=%%B"
  set "all=%%C"
)
del test.tmp
 
echo yes = %yes%
echo no  = %no%
echo all = %all%
 
::optional code to get the leading character
set "yes=%yes:~0,1%"
set "no=%no:~0,1%"
set "all=%all:~0,1%"
 
echo yes character = %yes%
echo no  character = %no%
echo all character = %all%


Thanks

Dave Benham

Re: Determine Yes/No/All string for current locale

Posted: 19 Feb 2014 21:20
by carlos
I think that you not need all the list for all the responses, you need get the response in the specific language.
the copy prompt confirmation is different from the ctrl+c prompt confirmation:

the copy prompt:

Code: Select all

Overwrite file.tmp? (Yes/No/All): 


the ctrl+c prompt:

Code: Select all

Terminate batch job (Y/N)? 


the del prompt looks like the the ctrl+c prompt:

Code: Select all

C:\dev\file.tmp, Delete (Y/N)? 


Then you can determine the local answer for yes and no with this piece of code:

Code: Select all

@echo off
setlocal enabledelayedexpansion

type nul >foo.tmp
set "p="
for %%_ in ("foo.tmp"
) do for /f "tokens=*" %%# in (
'del /p "%%~f_" ^<nul'
) do (
set "p=%%#"
set "p=!p:%%~f_=!"
set "p=!p:(=!"
set "p=!p:)=!"
set "p=!p:?=!"
)
del /q foo.tmp

for %%# in (%p%) do set "p=%%#"
for /f "tokens=1,2 delims=/ " %%a in (
"!p!") do (
set "yes=%%a"
set "no=%%b"
)

echo yes:%yes%
echo no:%no%

Re: Determine Yes/No/All string for current locale

Posted: 19 Feb 2014 21:22
by carlos
my above code tested on english and spanish:

spanish:

Code: Select all

yes:S
no:N

Re: Determine Yes/No/All string for current locale

Posted: 19 Feb 2014 21:30
by carlos
anyways your code works ok on spanish dbenham:

Code: Select all

yes = Sí
no  = No
all = Todos
yes character = S
no  character = N
all character = T

Re: Determine Yes/No/All string for current locale

Posted: 19 Feb 2014 21:39
by carlos
in xp spanish this is the prompt of copy /-y:

Code: Select all

C:\dev>copy /-y nul foo.tmp
¿Sobrescribir foo.tmp? (Sí/No/Todos):

Re: Determine Yes/No/All string for current locale

Posted: 19 Feb 2014 21:47
by carlos
dbenham I also think that your method is needed, because for example:


translate:
yes
no

from english to albanian:
po
jo

jo is no, and j means no in albanian, but yes on german (ja)

is only a example (not tested on windows in albanian).

Re: Determine Yes/No/All string for current locale

Posted: 20 Feb 2014 01:41
by jeb
I can confirm, that it's work also in german.

test.tmp überschreiben? (Ja/Nein/Alle):


But it can fail when your temp folder is not standard, like temp=c:\my (special) temp.

c:\my (special) temp\g überschreiben? (Ja/Nein/Alle):


jeb

Re: Determine Yes/No/All string for current locale

Posted: 20 Feb 2014 08:36
by dbenham
Thanks Carlos for the confirmation.

Thanks also jeb. I can protect against non-standard TEMP folder paths containing ( / or ) by using PUSHD to work directly from the TEMP folder.


Dave Benham

Re: Determine Yes/No/All string for current locale

Posted: 21 Oct 2020 09:25
by isidroco
This is Debham code perfectioned to use TEMP folder and two steps: First isolates prompt section (using ? as delimiter) from path name (solves special TEMP folder names), and then parses that as before, tested on XP and win 7:

Code: Select all

@echo off
setlocal

copy /y nul %TEMP%\test.tmp >nul
for /f "tokens=2* delims=?" %%A in (
  '^<nul copy /-y nul "%TEMP%\test.tmp"'
) do set allquestions=%%A
for /f "tokens=2-4 delims=(/)" %%A in (
  "%allquestions%"
) do (
  set yes=%%A
  set no=%%B
  set all=%%C
)
del %TEMP%\test.tmp

echo yes = %yes%
echo no  = %no%
echo all = %all%

REM optional code to get the leading character
set yes=%yes:~0,1%
set "no=%no:~0,1%"
set "all=%all:~0,1%"

echo yes character = %yes%
echo no  character = %no%
echo all character = %all%

Re: Determine Yes/No/All string for current locale

Posted: 28 Oct 2020 15:16
by jfl
For French, dbenham's code also works fine, and returns:

Code: Select all

C:\Temp>yes_no.bat
yes = Oui
no  = Non
all = Tous
yes character = O
no  character = N
all character = T

C:\Temp>
Note that isidroco's code does not work, because in French versions of Windows, the copy prompt does not contain a '?' character:

Code: Select all

C:\Temp>copy /-y nul %TEMP%\test.tmp
Remplacer C:\Users\ADMINI~1\AppData\Local\Temp\test.tmp (Oui/Non/Tous) :
        0 fichier(s) copié(s).

C:\Temp>

Re: Determine Yes/No/All string for current locale

Posted: 28 Oct 2020 15:20
by dbenham
Thanks jfl

Re: Determine Yes/No/All string for current locale

Posted: 28 Oct 2020 17:40
by isidroco
Good catch jfl , can you please try replacing ? with : in delimiter, that will possibly work in all languages, because : is not a valid path/filename char so it's present in exactly two places leaving (Y/N/A) section isolated. The other idea I had is to use an uncommon char (not used in temp path) in test filename (such as @ or #) and use that as delimiter instead of ?.

Code: Select all

@echo off
setlocal

copy /y nul %TEMP%\test#.tmp >nul
for /f "tokens=2* delims=:" %%A in (
  '^<nul copy /-y nul "%TEMP%\test#.tmp"'
) do set allquestions=%%A
echo . %allquestions%
for /f "tokens=2-4 delims=(/)" %%A in (
  "%allquestions%"
) do (
  set yes=%%A
  set no=%%B
  set all=%%C
)
del %TEMP%\test#.tmp

echo yes = %yes%
echo no  = %no%
echo all = %all%

rem optional code to get the leading character
set yes=%yes:~0,1%
set "no=%no:~0,1%"
set "all=%all:~0,1%"

echo yes character = %yes%
echo no  character = %no%
echo all character = %all%

Re: Determine Yes/No/All string for current locale

Posted: 29 Oct 2020 00:33
by siberia-man
It doesn't work in Russian (XP and WIN10)

Code: Select all

yes = да
no  = No
all = нет
yes character = д
no  character = N
all character = н
because

Code: Select all

>copy /-y nul zzz <nul
Скопировано файлов:         1.

>copy /-y nul zzz <nul
Заменить zzz [Yes (да)/No (нет)/All (все)]:
Скопировано файлов:         0.
UPDATED:

Russian words for Yes/No/All are Да/Нет/Все. However answers are accepted still in English.

Re: Determine Yes/No/All string for current locale

Posted: 29 Oct 2020 15:16
by jfl
@isidroco: Your latest script in post #12 works fine on French Windows:

Code: Select all

C:\Temp>post12
. \Users\ADMINI~1\AppData\Local\Temp\test#.tmp (Oui/Non/Tous)
yes = Oui
no  = Non
all = Tous
yes character = O
no  character = N
all character = T

C:\Temp>
Still, it needs lots of changes to support all possible cases. As the example in Russian has shown, Microsoft localizers can be quite creative!
Here's what I think must be done to handle all known cases (English, Spanish, German, French, Russian):
- Remove the trailing spaces and ':'.
- If the last character is ')', look for the matching '('.
- If the last character is ']', look for the matching '['.
- Remove all characters until that last matching '(' or '['. (This can be done in a very short loop, to handle the case of () or [] appearing in the file name.)
- Only then, use a for "delim=/" to split what remains in 3 parts.

Sample implementation:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

set "echo.var=call :echo.var"
goto :main

:echo.var %1=Variable name
echo set "%1=!%1!"
exit /b

:main
:# Try overwriting a file, to collect the question asked by the copy command
set "TEMP_FILE=%TEMP%\yes-no-all.tmp"
copy /y nul "%TEMP_FILE%" >nul
set "PromptLine="
for /f "delims=" %%A in (
  '^<nul copy /-y nul "%TEMP_FILE%"'
) do if not defined PromptLine set "PromptLine=%%A"
del "%TEMP_FILE%"
:# set "PromptLine=Overwrite foo.tmp? (Yes/No/All):"                &:# English
:# set "PromptLine=¿Sobrescribir foo.tmp? (Sí/No/Todos):"           &:# Spanish
:# set "PromptLine=foo.tmp überschreiben? (Ja/Nein/Alle):"          &:# German
:# set "PromptLine=Remplacer foo.tmp (Oui/Non/Tous) :"              &:# French
:# set "PromptLine=Заменить foo.tmp [Yes (да)/No (нет)/All (все)]:" &:# Russian
%echo.var% PromptLine
:# Remove the trailing spaces and :
set "YesNoAll=!PromptLine: =!"
set "YesNoAll=!YesNoAll::=!"
:# Find the last character, and the matching first character
set "LastC=!YesNoAll:~-1!"
set "FirstC="
if "!LastC!"==")" set "FirstC=("
if "!LastC!"=="]" set "FirstC=["
if not defined FirstC (
  >&2 echo Error: Can't find the matching character for "!LastC!"
  exit /b 1
)
set "YesNoAll=!YesNoAll:~0,-1!" &:# Remove that last character
:# Remove everything until that matching first character
:remove_more
set "YesNoAll0=!YesNoAll!"
set "YesNoAll=!YesNoAll:*%FirstC%=!"
if not "!YesNoAll!"=="!YesNoAll0!" goto :remove_more
%echo.var% YesNoAll
:# Extract the tokens
for /f "tokens=1-3 delims=/" %%A in ("!YesNoAll!") do (
  set "yes=%%A" & set "y=!yes:~0,1!"
  set "no=%%B"  & set "n=!no:~0,1!"
  set "all=%%C" & set "a=!all:~0,1!"
)
:# Display them all
for %%v in (yes no all y n a) do %echo.var% %%v
exit /b
Result on a French system:

Code: Select all

C:\Temp>t
set "PromptLine=Remplacer C:\Users\ADMINI~1\AppData\Local\Temp\yes-no-all.tmp (Oui/Non/Tous) : "
set "YesNoAll=Oui/Non/Tous"
set "yes=Oui"
set "no=Non"
set "all=Tous"
set "y=O"
set "n=N"
set "a=T"

C:\Temp>
Result with the Russian test string:

Code: Select all

#2 E:on V:on C:\JFL\Temp>t
# Заменить foo.tmp [Yes (да)/No (нет)/All (все)]:
# Yes(да)/No(нет)/All(все)
set "yes=Yes(да)"
set "no=No(нет)"
set "all=All(все)"
set "y=Y"
set "n=N"
set "a=A"

#2 E:on V:on C:\JFL\Temp>

Re: Determine Yes/No/All string for current locale

Posted: 29 Oct 2020 17:00
by siberia-man
At least this one covers both English (WIN10) and Russian (XP and WIN10) versions. Based on my results I can suppose that it could cover others as well. At least in the frame of the supported formats:

Code: Select all

@echo off

setlocal

set "ans_yes="
set "ans_no="
set "ans_all="

copy /y nul zzz >nul

for /f "tokens=2-7 delims=[(/)]" %%a in ( '
	copy /-y nul zzz ^<nul
' ) do if not defined ans_yes if "%%~e" == "" (
	rem                 %a  %b %c  %d   %e   %f
	rem Overwrite zzz? (Yes/No/All):
	set "ans_yes=%%~a"
	set "ans_no=%%~b"
	set "ans_all=%%~c"
) else (
	rem               %a   %b  %c  %d   %e   %f
	rem Заменить zzz [Yes (да)/No (нет)/All (все)]:
	set "ans_yes=%%~a"
	set "ans_no=%%~c"
	set "ans_all=%%~e"
)

del /q zzz

set "ans_yes=%ans_yes: =%"
set "ans_no=%ans_no: =%"
set "ans_all=%ans_all: =%"

set "ans_y=%ans_yes:~0,1%"
set "ans_n=%ans_no:~0,1%"
set "ans_a=%ans_all:~0,1%"

set ans_