tags:

views:

1310

answers:

5

Hi,

I receive a file that contains the following:

\direcotry1\directory2\directory3\file1
\direcotry1\file2
\direcotry1\directory2\directory3\directory4\file3
\direcotry1\file4
\direcotry1\directory2\file5
file6

The amount of files in the file and the amount of directories are variable.

What I need is the path only.

\direcotry1\directory2\directory3\ for file1
\direcotry1\ for file2
\direcotry1\directory2\directory3\directory4\ for file3
\direcotry1\ for file4
\direcotry1\directory2\ for file5
and nothing for file6

I used the variable %%~pi which works for all except for the last one. For the last one it returns \cft\
I guess the \cft\ is returned as the program that is calling the bat file launches it from there.

FOR /F %%i in (test.txt) DO (
  echo %%~pi
  command1
  command2
)

Does anyone know how I can avoid that the batfile returns \cft\? I want the bat to return nothing when there's no path.

Thanks a lot in advance for your help.

A: 

Update2:

As Lieven noted, if you can enforce that everything starts with "\" in your test.txt file, then you can use this code:

@echo off
FOR /F %%i in (test.txt) DO (
  if not "%%~pi" == "\" echo %%~pi
)

Update:

Actually, after reading your question again, I noticed that what you need is an EXIST statement..

FOR /F %%i in (test.txt) DO ( if exist %%i echo %%~pi command1 command2 )

Is this what you need?

My original post...

When you call the batch file, simply do:

yourbatchfile.bat >nul 2>nul

Anything going to stdout and stderr (your screen display) will be piped to no where, and no appear. Note that absolutely nothing will be output from that batch file...

Wadih M.
Your updated approach won't work if there is a file named file6 in the actual path.
schnaader
You're right. I'm doing another update.
Wadih M.
A: 

It seems this is due to the missing backslash in front of file6.
Isn't it possible to change your inputs to always have a leading backslash?

Your input would then become

\directory1\directory2\directory3\file1 
\directory1\file2 
\directory1\directory2\directory3\directory4\file3 
\directory1\file4 
\directory1\directory2\file5 
\file6
Lieven
unfortunately I can't put the leading backslash.It's an output file that comes from an FTP server.I do for example a dir test* and it returns me a file that contains all the files that start with test.
@vesperdolphin - I'd go with schnaader's response then.
Lieven
How can I use AND OR in batch?if variable==1 OR variable==2 (command1command2)
+2  A: 

You can store the directory you want to ignore in a variable:

FOR %%i in (file) do set ignoredir=%%~pi
FOR /F %%i in (test.txt) DO (
  if not %%~pi == %ignoredir% echo %%~pi
)
set ignoredir=

This works as expected. Output:

\direcotry1\directory2\directory3\
\direcotry1\
\direcotry1\directory2\directory3\directory4\
\direcotry1\
\direcotry1\directory2\
schnaader
Hi what's in file?The output is variable so I never know upfront which directories I will get.
Note that the first FOR doesn't read from a file, it just parses the directory for the string "file" (could also be "fsdjlkbfds") which results in the actual directory (was "\cft\" in your case) so it can be ignored afterwards.
schnaader
+1. Works as expected.
Lieven
A: 

Batch files are ok for simple tasks, but as your demands grows you should think about switching to better scripting language.

Example in Python:

import os.path
for line in open('file.txt'):
  line = line.strip()
  print os.path.dirname(line)
  print os.path.basename(line)

This code fragment is pretty obvious even without comments.

Jiri
+2  A: 

After doing some testing, it appears that "%%~pi" will prefix the current directory to every element that does not start with "\". I gather that it assumes this is the case since that would be the file you'd open if you just used "file" - similarly "x\y" would be the file "\x\y".

For example, the following script:

@echo off
for /f %%i in (test.txt) DO (
    echo %%~pi
)

when run on the following file:

\directory1\directory2\directory3\file1
\directory1\file2
\directory1\directory2\directory3\directory4\file3
\directory1\file4
\directory1\directory2\file5
file6
x\y
\z

will produce (I'm in the \Documents and Settings\Administrator directory):

\directory1\directory2\directory3\
\directory1\
\directory1\directory2\directory3\directory4\
\directory1\
\directory1\directory2\
\Documents and Settings\Administrator\
\Documents and Settings\Administrator\x\
\

So the answer is simple. Detect first those lines that don't begin with "\" and treat them specially. The following script:

@echo off
setlocal enableextensions enabledelayedexpansion
for /f %%i in (test.txt) DO (
    set ch0=%%i
    set ch0=!ch0:~0,1!
    if not "!ch0!"=="\" (
        echo.
    ) else (
        echo.%%~pi
    )
)
endlocal

generates your desired output, as follows:

\directory1\directory2\directory3\
\directory1\
\directory1\directory2\directory3\directory4\
\directory1\
\directory1\directory2\


\

The setlocal/endlocal is something I put in most of my scripts nowadays since it prevents environment variables from leaking up one level and delayed expansion is brilliant (using "!" instead of "%").

I use a ch0 temporary variable to get the first character of the file ("!ch0:~0,1!" is a substring operator, "get one character at offset 0 of ch0 variable", and you can use the "%" version as well if you're not doing delayed expansion).

Then I compare it to "\". If it is a slash, I echo the "%%~pi", otherwise I just output a blank line as per your spec.

paxdiablo
How can I use AND OR in batch?if variable==1 OR variable==2 (command1command2)
thanks for your reply. I'm testing
So I want to try if not "!ch0!"=="/" || "!ch0!"=="\" (but it doesn't seem to work
I don't have a Windows box handy to test but you could just "if "!ch0!"=="\" set ch0=/", "if not "!ch0!"=="/" ...". This would force "\" to become "/" (and "/" will stay "/") then you just check for "/".
paxdiablo
AND can similarly be done: if cond1 (if cond2 (action-if-both-true)).
paxdiablo
I've never seen that complicated an expression in a single if (either the OR or the AND variant) - I'm not sure it can be done in cmd.exe without the trickery in my last two comments.
paxdiablo
Another question@echo offsetlocal enableextensions enabledelayedexpansionfor /f %%i in (test.txt) DO ( set ch0=%%i set ch0=!ch0:~0,1! if not "!ch0!"=="\" ( echo. ) else ( SET FTPDIR=%%~pi echo %FTPDIR% echo.%%~pi ))endlocal
in above code I want to echo %FTPDIR% but it gives as output ECHO is off.Any idea why?
It's because I need the FTPDIR, which should contain %%~pi, further on in my program
FTPDIR isn't set at that point (more precisely, isn't set at the time the IF statement is parsed, since it's set only when that statement is executed) so it's like you just did "echo" (which outputs "echo is off"). Try the delayed expansion !FTPDIR! instead.
paxdiablo