iT邦幫忙

1

bat檔搜尋路徑指定excel檔案名稱最後2碼,複製

  • 分享至 

  • xImage

請教高手們一下,小弟要做一個bat批次檔複製excel檔案遇到一個問題
我的目標檔案路徑在D:\TTT
檔案名稱是像下面(1個資料夾有70幾個工作簿)
屠仔場一廠_20230227(NEW)---牛肉
屠仔場一廠_20230227(NEW)---羊肉
屠仔場一廠_20230227(NEW)---羊肉-己收費
副檔名是.xlsx
現在我要指定最後面2碼是"牛肉"或"羊肉"的檔案(粗體部份),複製到
C:\Users\User\Desktop\1

現在卡在不管怎麼複製都複製不過來,看看是否有高手大師們幫忙看一下,小弟是那裡有錯誤?謝謝您們~~~

@echo off
chcp 65001

set "source_path=D:\TTT\"
set "target_path=C:\Users\User\Desktop\1\"
set "file_ext=xlsx"

for %%f in ("%source_path%*.*") do (
    set "file_name=%%~nf"
    set "last_two=!file_name:~-2!"
    set "last_four=!file_name:~-4!"
    if /i "!last_two!"=="牛肉" (
        if /i "%%~xf"==".%file_ext%" (
            copy "%%f" "%target_path%"
        )
    ) else if /i "!last_four!"=="羊肉" (
        if /i "%%~xf"==".%file_ext%" (
            copy "%%f" "%target_path%"
        )
    )
)

echo Done.
pause

alien663 iT邦研究生 4 級 ‧ 2023-03-13 09:50:30 檢舉
你echo %file_name%就會知道問題出在哪裡了
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

1
re.Zero
iT邦研究生 5 級 ‧ 2023-03-13 18:26:39
最佳解答
  • 因為你有用到 chcp 65001 命令,請確認你的 .bat/.cmd 檔案的存檔格式是 UTF-8 without BOM 格式。
    否則會導致 Win-Cmd (命令提示字元) 對 .bat/.cmd 檔案串流做字元解析時出錯。
    ( 有時是 Win-Cmd 切換異常,這要看 Windows 版本與環境;
    可透過 右擊 Win-Cmd 視窗左上角圖示 -> [內容] -> [選項]標籤頁
    查看下方 目前的字碼頁 的內容確認。 )
    另,通常繁中版 Windows 平台的各種 文字/程式碼 編輯器,在處理 .bat/.cmd 時,有可能使用系統相容性的組態而使用 Big5 編碼(chcp 950) 處理檔案。

  • 因為你有使用 Delayed Expansion 語法 (變數的驚嘆號之使用,Ex:!delayedVar!), 請確認你的 Win-Cmd 環境有啟用該功能。
    (我記得預設是沒有啟用;至少我這邊沒有預設啟用,因為會產生另一種麻煩~)
    不然就是在 .bat/.cmd 內使用 setlocal EnableDelayedExpansion 來改變處理模式。
    ( setlocal 命令是常見用法; setlocal 命令只在 .bat/.cmd 檔案內有效, 詳情請參閱這裡。 )

  • 我不懂你的 "!last_four!"=="羊肉" 部分:用「最後的四個字」與「兩個字的"羊肉"」做比較?
    可能你有啥考量,我就不動了~

以下小修正版:

@echo off
@rem ## 請確認你的 `.bat/.cmd` 檔案的存檔格式是 `UTF-8 without BOM` 格式。 
chcp 65001
setlocal EnableDelayedExpansion

@rem ## 後續我都沒動~
set "source_path=D:\TTT\"
set "target_path=C:\Users\User\Desktop\1\"
set "file_ext=xlsx"

for %%f in ("%source_path%*.*") do (
    set "file_name=%%~nf"
    set "last_two=!file_name:~-2!"
    set "last_four=!file_name:~-4!"
    if /i "!last_two!"=="牛肉" (
        if /i "%%~xf"==".%file_ext%" (
            copy "%%f" "%target_path%"
        )
    ) else if /i "!last_four!"=="羊肉" (
        if /i "%%~xf"==".%file_ext%" (
            copy "%%f" "%target_path%"
        )
    )
)

echo Done.
pause
alien663 iT邦研究生 4 級 ‧ 2023-03-14 09:04:06 檢舉

Zero大大,我想順便請問一下,我拿他的邏輯去測試時發現,file_name裡面的值根本不是檔案名稱,而是echo off(每一筆皆是如此),這才導致沒有辦法順利複製檔案的狀況發生,後來改成UTF-8 with BOM也是。
這也是我後來直接改變程式碼,改用萬用字元直接弄檔案的原因,想請問關於這問題有沒有一些資訊能夠提供?

re.Zero iT邦研究生 5 級 ‧ 2023-03-14 19:46:51 檢舉

@alien663:

後來改成UTF-8 with BOM也是

在 Win-Cmd 使用 UTF-8 with BOM.bat/.cmd, 會因為檔頭的 BOM (EF BB BF 位元組序列)而導致首行命令處理異常; 若 Win-Cmd 尚未改善這部分, 不建議使用 (至少我在 Win10 測試還是會異常)。

file_name裡面的值根本不是檔案名稱,而是echo off(每一筆皆是如此)

印象中我在 XP 或 Win7 時期, 不知啥狀況下有遇過, 但沒追究過原因; 而我這邊在 Win10 上做了幾個簡單測試, 做不出你的結果, 也就無依據能推測, 抱歉。 只是提醒一下, .bat/.cmd 因為字元編碼所發生的異常, 跟 Win-Cmd 版本、 Win-Cmd runtime code-page (or 因 OS 語言所產生的相容性組態環境)、 .bat/.cmd 字元編碼這三者常互有關係。

這也是我後來直接改變程式碼,改用萬用字元直接弄檔案的原因,想請問關於這問題有沒有一些資訊能夠提供?

我這因為 .bat/.cmd 字元編碼所發生的異常所寫的內容, 是基於我過去的 經驗 + Google + wiki 所得的結論, 不好說哪邊有相關資訊 (畢竟年代久遠都忘了~)。 現在一時想到的,就這裡 與 Google:windows chcp site:stackoverflow.com 吧。

alien663 iT邦研究生 4 級 ‧ 2023-03-16 15:17:10 檢舉

好的,非常感謝你提供的資訊~~

2
alien663
iT邦研究生 4 級 ‧ 2023-03-13 09:10:17

有些地方可以寫得更簡單點,除非你的目錄會有空白,不然其實不太需要雙引號。
你的需求可以直接用正規表示法解決掉,直接把符合需求的檔案直接複製過去既可

@echo off
chcp 65001
set source_path=D:\TTT\
set target_path=C:\Users\User\Desktop\1\
copy %source_path%\*牛肉.xlsx %target_path%
copy %source_path%\*羊肉.xlsx %target_path%
echo Done.
pause
re.Zero iT邦研究生 5 級 ‧ 2023-03-13 18:32:12 檢舉
alien663 iT邦研究生 4 級 ‧ 2023-03-14 08:45:13 檢舉

喔喔,是我用詞錯誤了,感謝提醒~

我要發表回答

立即登入回答