Atur tidak pengaturan dalam skrip batch CMD

2

Saya mencoba menulis skrip yang akan menemukan semua persimpangan direktori pada disk dan kemudian membuatnya kembali di lokasi lain. Pertama-tama, saya harus menemukan semua persimpangan dan mengedit output agar lebih mudah dibaca.

Ini adalah test.txt:

 Volume in drive C has no label.
 Volume Serial Number is A0D2-DFB0

 Directory of C:\

14.07.2009.  06:08    <JUNCTION>     Documents and Settings [C:\Users]
13.01.2015.  10:26    <JUNCTION>     Users [E:\Users]
               0 File(s)              0 bytes

 Directory of C:\ProgramData

14.07.2009.  06:08    <JUNCTION>     Application Data [C:\ProgramData]
14.07.2009.  06:08    <JUNCTION>     Desktop [C:\Users\Public\Desktop]
14.07.2009.  06:08    <JUNCTION>     Documents [C:\Users\Public\Documents]
14.07.2009.  06:08    <JUNCTION>     Favorites [C:\Users\Public\Favorites]
14.07.2009.  06:08    <JUNCTION>     Start Menu [C:\ProgramData\Microsoft\Windows\Start Menu]
14.07.2009.  06:08    <JUNCTION>     Templates [C:\ProgramData\Microsoft\Windows\Templates]
               0 File(s)              0 bytes

 Directory of C:\ProgramData\Oracle\Java\javapath

24.12.2014.  18:22    <SYMLINK>      java.exe [D:\Programs\Java 8u25\bin\java.exe]
24.12.2014.  18:22    <SYMLINK>      javaw.exe [D:\Programs\Java 8u25\bin\javaw.exe]
24.12.2014.  18:22    <SYMLINK>      javaws.exe [D:\Programs\Java 8u25\bin\javaws.exe]
               3 File(s)              0 bytes

     Total Files Listed:
               3 File(s)              0 bytes
               8 Dir(s)  16.309.276.672 bytes free

- Ini adalah skrip (belum selesai) yang saya jalankan:

echo on

cd \

set start=
set end=
set paths=

type NUL > output.txt

for /f "tokens=* skip=3" %%l in (C:\test.txt) do (
for /f "tokens=1" %%d in ("%%l") do (
 if %%d==Directory (
    for /f "tokens=3" %%p in ("%%l") do (
      set start="%%p"
    )
 ) else (
   for /f "tokens=3" %%j in ("%%l") do (
      if %%j==^<JUNCTION^> (
          for /f "tokens=4*" %%h in ("%%l") do (
            set end="%%h"
            echo %start% %end% >> output.txt

          )
       )
    )
 )
)
)

Masalahnya adalah bahwa output.txt berakhir dengan beberapa baris "Echo ON" alih-alih memiliki jalur di sana. Jika saya mengganti "% mulai%% akhir%" dengan string apa pun (mis. "Sosis") saya mendapatkan output.txt diisi dengan sosis. Jika saya menjalankan echo set% end% setelah skrip berjalan, output adalah "Templates" yang diharapkan. Saya menduga perintah set tidak mengatur apa pun sampai salah satu loop selesai.

Apakah saya benar? Apakah ada jalan keluarnya? Saya benar-benar perlu menjalankan ini di CMD karena harus dijalankan dari disk Windows Repair.

P.S. Saya tahu kode saya tidak akan berfungsi untuk tujuan saya walaupun dengan program ini diperbaiki, tetapi saya baru saja sampai di sana, hal pertama yang pertama.

Karlovsky120
sumber
set tidak berfungsi di () karena file batch sebenarnya tidak diproses dalam urutan itu. Pada dasarnya seluruh skrip tanpa kode antara () dieksekusi, dan kemudian bagian antara () dijalankan. Anda dapat mengatasinya dengan menulis kode kedua dalam file batch kedua dan menjalankannya dalam pernyataan FOR Anda. Yang pertama, Anda dapat menempatkan garis yang ditetapkan sepenuhnya pada garis FOR dan menghapus () semuanya.
LPChip
juga, untuk menghilangkan yang lain (), gunakan variabel goto dan: variabel.
LPChip
@ LPChip - solusi Anda dapat bekerja, tetapi tidak untuk alasan Anda menyatakan
dbenham
@benham dengan segala cara mencerahkan kami mengapa Anda mengatakannya. Saya menemukan bahwa ketika saya memiliki skrip seperti ini, perintah SET selalu memiliki set variabel terakhir dalam loop, jadi saya menganggap itu tidak diproses dalam urutan yang sebenarnya.
LPChip

Jawaban:

1

Jika Anda menggunakan skrip asli Anda dan tambahkan setlocal enabledelayedexpansion Anda bisa mengganti %start% dan %end% oleh !start! dan !end! dan skrip Anda akan berfungsi seperti yang Anda inginkan.

Skrip Anda tidak mengizinkan kosong pada nama file, jadi saya usulkan skrip dimodifikasi berikut:

echo off

setlocal enabledelayedexpansion

cd \

set start=
set end=
set paths=

type NUL > output.txt

for /f "tokens=* skip=3" %%l in (C:\test.txt) do ^
for /f "tokens=1-2*" %%d in ("%%l") do ^
if %%d==Directory (
    set start="%%f"
) else (
    for /f "tokens=3*" %%j in ("%%l") do ^
if %%j==^<JUNCTION^> (
            for /f "tokens=1 delims=[" %%n in ("%%k") do set end=%%n
            set end="!end:~0,-1!"
            echo !start! !end! >> output.txt

        )
)

Saya telah melakukan dua hal tambahan di sini: -

  1. Saya telah menghapus tanda kurung dari perintah yang tidak membutuhkannya (sayangnya, baris baru setelah karakter lanjutan ^ tidak dapat diindentasi, yang merusak pemformatan yang kedua if ).
  2. Saya telah menghapus yang tidak perlu for loop sementara pada saat yang sama memungkinkan untuk tertanam kosong di direktori dan nama file.

Saya telah meninggalkan mereka, tetapi inisial cd \ dan set inisialisasi tidak diperlukan, meskipun Anda mungkin ingin menghapus start dan end sebelum keluar.

AFH
sumber
Terima kasih banyak, inilah tepatnya yang saya cari.
Karlovsky120
1

Menggantikan echo %start% %end% >> output.txt dengan call :forecho dan lampirkan cuplikan kode berikutnya di bawah baris skrip terakhir:

goto :eof

:forecho
    echo %start% %end% >> output.txt
goto :eof

Masalahnya terletak pada fakta bahwa% variabel% diperluas, perintah demi perintah, pada waktu parse daripada pada waktu eksekusi. Dan semua cuplikan kode terlampir ( tanda kurung ) dianggap sebagai satu-satunya perintah.

Agar aman, mulai skrip Anda dengan

@ECHO OFF >NUL
@SETLOCAL enableextensions disabledelayedexpansion

Seluruh skrip dapat sebagai berikut:

@ECHO OFF >NUL
@SETLOCAL enableextensions disabledelayedexpansion
cd \
set start=
set end=
set paths=
type NUL > output.txt

for /f "tokens=* skip=3" %%l in (C:\test.txt) do (
for /f "tokens=1" %%d in ("%%l") do (
 if %%d==Directory (
    for /f "tokens=3" %%p in ("%%l") do (
      set start="%%p"
    )
 ) else (
   for /f "tokens=3" %%j in ("%%l") do (
      if %%j==^<JUNCTION^> (
          for /f "tokens=4*" %%h in ("%%l") do (
            set end="%%h"
            call :forecho
          )
       )
    )
 )
)
)
@ENDLOCAL
goto :eof

:forecho
    echo %start% %end% >> output.txt
goto :eof
JosefZ
sumber