遇到批处理脚本问题

时间:2011-05-03 14:49:11

标签: file unicode batch-file

我有一个批处理脚本,它使用sqlcmd调用将SELECT语句的结果拉入名为temp.txt的文件中。数据中有一些外来字符要求我们使用Unicode,因此temp.txt是Unicode(代码页65001)。

一旦数据在temp.txt中,脚本会计算行数并附加一些标题。为了做到这一点,它必须创建一个新文件(让我们称之为newfile.txt),添加标题和行计数,然后将每行从temp.txt复制到newfile.txt。

除了从temp.txt复制的第一行中有一个Unicode字节顺序标记外,所有这一切都正常。这意味着第一行,而不是这样:

1, Custom Page

看起来像这样:

1, Custom Page

我无法弄清楚这是解决这个问题的最佳方法。

如果我能告诉sqlcmd给我一个没有BOM的Unicode,那就完美了 - 试着用谷歌搜索,无法理解。

如果我能弄清楚如何编写批处理文件FOR循环,在temp.txt中复制时删除第一行的前三个字符,我会尝试,但是在一些之后谷歌搜索和实验我很沮丧。

对于记录,相关代码如下所示:

::%1 = sql file to call; %2 = filename to be created; %3 = header for file; %4 = data type row for file
sqlcmd -I -f 65001 -W -k 1 -h -1 -s "," -S servername -d dbname -i %1 -o temp.txt
set counter=0
for /f %%a in (temp.txt) do set /a counter+=1
echo ^^!total rows=%counter% >> %2
echo !str1! >> %2
echo !str2! >> %2
for /F "delims=¶" %%i in (temp.txt) do ( echo %%i >> %2 )

请帮助我,我对这个荒谬的小问题感到疯狂。

1 个答案:

答案 0 :(得分:1)

您可以尝试

chcp 65001
在调用sqlcmd之前,在批处理脚本中

。它不是完全直观的,但可能起到了作用。

如果所有其他方法都失败了,请让自己的版本为 bomstrip ,并且您应该是明确的。

HTH

更新

我有一个Windows的“固定”版本,它将以二进制模式重新打开stdin / stdout,这样你就可以避免自动为你转换行尾(原文如此!):

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

void
usage(char *prog)
{
    fprintf(stderr, "usage: %s\n", prog);
    exit(1);
}

int
main(int argc, char *argv[])
{
    size_t nread;
    char buf[65536];
    char *utf8bom = "\xef\xbb\xbf";

    if (argc > 1)
        usage(argv[0]);

    /*
     * On Windows, we need to use binary mode to read/write non-text archive
     * formats.  Force stdin/stdout into binary mode in case that is what
     * we are using.
     */
#ifdef WIN32
    if (fmt != archNull)
    {
        setmode(fileno(stdout), O_BINARY);
        setmode(fileno(stdin), O_BINARY);
    }
#endif
    nread = fread(buf, 1, strlen(utf8bom), stdin);
    if (nread == 0)
        return 0;
    if (strcmp(buf, utf8bom) != 0)
        fwrite(buf, 1, nread, stdout);
    for (;;) {
        nread = fread(buf, 1, sizeof buf, stdin);
        if (nread < 0)
            exit(1);
        if (nread == 0)
            return 0;
        fwrite(buf, 1, nread, stdout);
    }
    return 0;
}

现在你可以做到:

> .\bomstrip.exe < withoutbom > test
> md5sum.exe withoutbom test
f9f2e33bb16636f990180fa3fcbc93cb *withoutbom
f9f2e33bb16636f990180fa3fcbc93cb *test