あー、こりゃ(すでに修正済みの)バグだわ。
どーすっかね。
awkについて語るスレ $2
625 デフォルトの名無しさん [sage] 2011/08/16(火) 22:48:21.64 ID: Be:
ここって生きてますか?
626 デフォルトの名無しさん [sage] 2011/08/18(木) 01:56:26.63 ID: Be:
生きてますん
627 デフォルトの名無しさん [sage] 2011/08/19(金) 00:53:44.39 ID: Be:
生きていることを願って質問を。
WIN32のEXE一つで、下のTEST.AWKがマトモに動くAWKを探しています。
これら以外にありますか?
http://hinadori.atnifty.com/~wills/program/gawkm115.zip
http://my.vector.co.jp/servlet/System.FileDownload/download/http/0/376460/pack/win95/util/text/awk/gawk-mbcs-win32-20051223.zip?ds
http://my.vector.co.jp/servlet/System.FileDownload/download/http/0/80308/pack/win95/util/text/awk/mw32r27.lzh?ds
Cygwin版も試したのですがダメでした。
TEST.AWK
{ gsub("[0-9]","x",$0) ; gsub("ソ","ソ",$0) ; gsub("T","T",$0) ; print }
TEST.DAT
アイウエオカキクケコサシスセソ
ココココサフサコココココ
ココココサフサココココ
ココココサフサコココココ
ココココサフサコココココ
サフサフサフサフサフサ
ココココサフサコココココ
ココココサフサココココ
ココココサフサコココココ
ココココサフサコココココ
サフサフサフサフサフサ
628 627 [sage] 2011/08/19(金) 01:00:20.60 ID: Be:
TEST.DATは、空白が入っています。
専ブラのポップアップをコピペして下さい。
629 デフォルトの名無しさん [sage] 2011/08/19(金) 06:26:54.92 ID: Be:
ウチに帰ってから調べてみるよ
630 デフォルトの名無しさん [sage] 2011/08/19(金) 11:02:41.54 ID: Be:
>>627-628
cygwinのawk(GNU Awk 3.1.8)で動くけど、どうなるはずがどう動かないと言っている?
>627のtest.datなら、当然「ソ」だけが変換されるけど。
631 デフォルトの名無しさん [sage] 2011/08/19(金) 11:55:06.25 ID: Be:
(CygwinならUTF8じゃないとうまく動かないけど)Shift JISで動作させたいってことかな?
事前にTEST.DATをnkf -wに通したら駄目かな。
632 629 [sage] 2011/08/19(金) 21:59:57.43 ID: Be:
>>627
スクリプトもDATもSJISで試したけど、上記3つのうち、gawk-mbcs-win32-20051223.zipはダメだったよ。
1行目がこんなんなる。
アxxエオカキクxコサxxxソ
手持ちの
GNU Awk 3.1.7(windows special Nov 24 2009)
で、--ctype=SJISやっても同じ結果になるね。
スクリプト、DATをUTF-8にして、--ctype=UTF8やってリダイレクトしたファイルは正常な結果が出るよ。
リダイレクトしないでコマンドプロンプトに表示させると化けるけど。
633 デフォルトの名無しさん [sage] 2011/08/19(金) 23:18:25.14 ID: Be:
EUCなら半角カナもうまくやってくれるんだが…
このバグは、ShiftJIS でしかでません。
また、上の例で言うと、[0-9] を [0123456789] にすると正しい出力となります。
ShiftJISでの半角カナが、1バイトなんだけど wchar_t にしたときの値が
255 (0xff) を超えちゃうのをきちんと扱ってないからなんですよね。
変更済みのコードはこんなの↓
(折角だから関数丸ごと)
/* Helper function for re_compile_fastmap.
Compile fastmap for the initial_state INIT_STATE. */
static void
re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
char *fastmap)
{
volatile re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
int node_cnt;
int icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE));
for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt)
{
int node = init_state->nodes.elems[node_cnt];
re_token_type_t type = dfa->nodes[node].type;
if (type == CHARACTER)
{
re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c);
#ifdef RE_ENABLE_I18N
if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
{
unsigned char *buf = re_malloc (unsigned char, dfa->mb_cur_max), *p;
wchar_t wc;
mbstate_t state;
p = buf;
*p++ = dfa->nodes[node].opr.c;
while (++node < dfa->nodes_len
&& dfa->nodes[node].type == CHARACTER
&& dfa->nodes[node].mb_partial)
*p++ = dfa->nodes[node].opr.c;
memset (&state, '\0', sizeof (state));
if (__mbrtowc (&wc, (const char *) buf, p - buf,
&state) == p - buf
&& (__wcrtomb ((char *) buf, towlower (wc), &state)
!= (size_t) -1))
re_set_fastmap (fastmap, 0, buf[0]);
re_free (buf);
}
#endif
}
else if (type == SIMPLE_BRACKET)
{
int i, ch;
for (i = 0, ch = 0; i < BITSET_WORDS; ++i)
{
int j;
bitset_word_t w = dfa->nodes[node].opr.sbcset[i];
for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)
if (w & ((bitset_word_t) 1 << j))
re_set_fastmap (fastmap, icase, ch);
}
}
#ifdef RE_ENABLE_I18N
else if (type == COMPLEX_BRACKET)
{
re_charset_t *cset = dfa->nodes[node].opr.mbcset;
int i;
# ifdef _LIBC
/* See if we have to try all bytes which start multiple collation
elements.
e.g. In da_DK, we want to catch 'a' since "aa" is a valid
collation element, and don't catch 'b' since 'b' is
the only collation element which starts from 'b' (and
it is caught by SIMPLE_BRACKET). */
if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0
&& (cset->ncoll_syms || cset->nranges))
{
const int32_t *table = (const int32_t *)
_NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
for (i = 0; i < SBC_MAX; ++i)
if (table[i] < 0)
re_set_fastmap (fastmap, icase, i);
}
# endif /* _LIBC */
/* See if we have to start the match at all multibyte characters,
i.e. where we would not find an invalid sequence. This only
applies to multibyte character sets; for single byte character
sets, the SIMPLE_BRACKET again suffices. */
if (dfa->mb_cur_max > 1
&& (cset->nchar_classes || cset->non_match || cset->nranges
# ifdef _LIBC
|| cset->nequiv_classes
# endif /* _LIBC */
))
{
unsigned char c = 0;
do
{
mbstate_t mbs;
wchar_t wc;
memset (&mbs, 0, sizeof (mbs));
if (__mbrtowc (&wc, (char *) &c, 1, &mbs) == (size_t) -2)
re_set_fastmap (fastmap, false, (int) c);
else if (0xff61 <= wc && wc <= 0xff9f) // half-width kana
re_set_fastmap (fastmap, false, (int) c);
}
while (++c != 0);
}
else
{
/* ... Else catch all bytes which can start the mbchars. */
for (i = 0; i < cset->nmbchars; ++i)
{
char buf[256];
mbstate_t state;
memset (&state, '\0', sizeof (state));
if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1)
re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
{
if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state)
!= (size_t) -1)
re_set_fastmap (fastmap, false, *(unsigned char *) buf);
}
}
}
}
#endif /* RE_ENABLE_I18N */
else if (type == OP_PERIOD
#ifdef RE_ENABLE_I18N
|| type == OP_UTF8_PERIOD
#endif /* RE_ENABLE_I18N */
|| type == END_OF_RE)
{
memset (fastmap, '\1', sizeof (char) * SBC_MAX);
if (type == END_OF_RE)
bufp->can_be_null = 1;
return;
}
}
}
/* Initialize DFA. We use the length of the regular expression PAT_LEN
as the initial length of some arrays. */
static reg_errcode_t
init_dfa (re_dfa_t *dfa, size_t pat_len)
{
unsigned int table_size;
#ifndef _LIBC
char *codeset_name;
#endif
memset (dfa, '\0', sizeof (re_dfa_t));
/* Force allocation of str_tree_storage the first time. */
dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE;
/* Avoid overflows. */
if (pat_len == SIZE_MAX)
return REG_ESPACE;
dfa->nodes_alloc = pat_len + 1;
dfa->nodes = re_malloc (re_token_t, dfa->nodes_alloc);
/* table_size = 2 ^ ceil(log pat_len) */
for (table_size = 1; ; table_size <<= 1)
if (table_size > pat_len)
break;
dfa->state_table = calloc (sizeof (struct re_state_table_entry), table_size);
dfa->state_hash_mask = table_size - 1;
dfa->mb_cur_max = MB_CUR_MAX;
#ifdef _LIBC
if (dfa->mb_cur_max == 6
&& strcmp (_NL_CURRENT (LC_CTYPE, _NL_CTYPE_CODESET_NAME), "UTF-8") == 0)
dfa->is_utf8 = 1;
dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII)
!= 0);
#else
# ifdef HAVE_LANGINFO_CODESET
codeset_name = nl_langinfo (CODESET);
# else
codeset_name = getenv ("LC_ALL");
if (codeset_name == NULL || codeset_name[0] == '\0')
codeset_name = getenv ("LC_CTYPE");
if (codeset_name == NULL || codeset_name[0] == '\0')
codeset_name = getenv ("LANG");
if (codeset_name == NULL)
codeset_name = "";
else if (strchr (codeset_name, '.') != NULL)
codeset_name = strchr (codeset_name, '.') + 1;
# endif
/* strcasecmp isn't a standard interface. brute force check */
#if 0
if (strcasecmp (codeset_name, "UTF-8") == 0
|| strcasecmp (codeset_name, "UTF8") == 0)
dfa->is_utf8 = 1;
#else
if ( (codeset_name[0] == 'U' || codeset_name[0] == 'u')
&& (codeset_name[1] == 'T' || codeset_name[1] == 't')
&& (codeset_name[2] == 'F' || codeset_name[2] == 'f')
&& (codeset_name[3] == '-'
? codeset_name[4] == '8' && codeset_name[5] == '\0'
: codeset_name[3] == '8' && codeset_name[4] == '\0'))
dfa->is_utf8 = 1;
#endif
/* We check exhaustively in the loop below if this charset is a
superset of ASCII. */
dfa->map_notascii = 0;
#endif
#ifdef RE_ENABLE_I18N
if (dfa->mb_cur_max > 1)
{
if (dfa->is_utf8)
{
#if !defined(__GNUC__) || __GNUC__ < 3
static short utf8_sb_map_inited = 0;
if (! utf8_sb_map_inited)
{
int i;
utf8_sb_map_inited = 0;
for (i = 0; i <= 0x80 / BITSET_WORD_BITS - 1; i++)
utf8_sb_map[i] = BITSET_WORD_MAX;
}
#endif
dfa->sb_char = (re_bitset_ptr_t) utf8_sb_map;
}
else
{
int i, j, ch;
dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
if (BE (dfa->sb_char == NULL, 0))
return REG_ESPACE;
/* Set the bits corresponding to single byte chars. */
for (i = 0, ch = 0; i < BITSET_WORDS; ++i)
for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)
{
wint_t wch = __btowc (ch);
if (wch != WEOF && !(0xff61<=wch && wch<=0xff9f))
dfa->sb_char[i] |= (bitset_word_t) 1 << j;
# ifndef _LIBC
if ((unsigned char)ch < 0x100 && wch != ch)
dfa->map_notascii = 1;
# endif
}
}
}
#endif
if (BE (dfa->nodes == NULL || dfa->state_table == NULL, 0))
return REG_ESPACE;
return REG_NOERROR;
}
実に美しくない○| ̄|_
> else if (0xff61 <= wc && wc <= 0xff9f) // half-width kana
以下略
sedコマンドで全ての2バイト文字を指定するには? | OKWave
こんにちは。
LinuxやWindows用のsedコマンドには、[・・・]という演算子によって、
特定の範囲の文字集合が指定できます。
例えば
sed "s/[a-zA-Z]//g" test.txt
というコマンドによって、test.txtから、アルファベットを削除する事ができます。
では、シフトJISコードにおいて、全ての2バイト文字を指定するにはどうすればよいのでしょうか?
シフトJISコードでは、最初の漢字が「亜」であり、最後の漢字が「黑」らしいので、
sed "s/[あ-んア-ン亜-黑]//g"
といったコマンドを試しましたが、これでは
「ー」「、」「。」「ぁぃぅぇぉ」といった文字が残ってしまいます。
結局は、シフトJISコードの2バイト文字の範囲を知りたいのですが、
調べてみても分かりませんでした。
ご存知の方がいらっしゃれば、情報提供をお願い致します。
そのsedがShift-JISの「1文字」を「1文字」として処理できるものである必要があります。
「マルチバイト文字に対応」と明記していないものでは、
[あ-んア-ン亜-黑]
は
「あ」の1バイト目
「あ」の2バイト目から「ん」の1バイト目
「ん」の1バイト目
...
とばらばらに解釈されている可能性があります。
あとは、Shift-JISのコード表を見れば、「あ-ん」には「ぁ」は入ってないし、句読点は別のところにあるのがわかると思います。
http://charset.7jp.net/sjis.html
> [・・・]という演算子
演算子ではないですが...
どの sed 使っているかわからないけど、亜-黑
という範囲指定で期待通りに動くかどうかはちと疑問。
最近の GNU sed なんかだと wchar_t に変換した後のコードポイントで指定されるから。
十六進記述ができて、マルチバイト文字をきちんと認識するのなら
[^\x00-\xff] あたり?
よんだ。
A couple Python-like features in C++11 ? The Endeavour
A couple Python-like features in C++11
by John on August 17, 2011
The new C++ standard includes a couple Python-like features that I ran across recently.
There are other Python-like features in the new standard, but here I'll discuss
range-based for-loops and raw strings.
In Python you loop over lists rather than rather than incrementing a loop counter
variable. For example,
Interview: SciRuby Team
F4S: What is SciRuby?
John Woods: The SciRuby Project is two things: a community and a set of libraries. We
think Ruby is a great language, and so do a lot of other people. We liked what had
been done with SciPy and NumPy, as far as opening up Python to those who had been
stuck in Matlab and R, and decided Ruby needed something similar.