??xml version="1.0" encoding="utf-8" standalone="yes"?>
Ҏ(gu)一Q?/p>
string WideToMutilByte(const wstring& _src)
{
int nBufSize = WideCharToMultiByte(GetACP(), 0, _src.c_str(),-1, NULL, 0, 0, FALSE);
char *szBuf = new char[nBufSize];
WideCharToMultiByte(GetACP(), 0, _src.c_str(),-1, szBuf, nBufSize, 0, FALSE);
string strRet(szBuf);
delete []szBuf;
szBuf = NULL;
return strRet;
}
wstring MutilByteToWide(const string& _src)
{
//计算字符?string 转成 wchar_t 之后占用的内存字节数
int nBufSize = MultiByteToWideChar(GetACP(),0,_src.c_str(),-1,NULL,0);
//?wsbuf 分配内存 BufSize 个字?br>wchar_t *wsBuf = new wchar_t[nBufSize];
//转化?unicode ?WideString
MultiByteToWideChar(GetACP(),0,_src.c_str(),-1,wsBuf,nBufSize);
wstring wstrRet(wsBuf);
delete []wsBuf;
wsBuf = NULL;
return wstrRet;
}
转蝲Qcsdn
q篇文章里,我将l出几种C++ std::string和std::wstring怺转换的{换方法?br>
W一U方法:(x)调用WideCharToMultiByte()和MultiByteToWideChar()Q代码如下(关于详细的解释,可以参考《windows核心~程》)Q?br>
#include <string>
#include <windows.h>
using namespace std;
//Converting a WChar string to a Ansi string
std::string WChar2Ansi(LPCWSTR pwszSrc)
{
int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);
if (nLen<= 0) return std::string("");
char* pszDst = new char[nLen];
if (NULL == pszDst) return std::string("");
WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL);
pszDst[nLen -1] = 0;
std::string strTemp(pszDst);
delete [] pszDst;
return strTemp;
}
string ws2s(wstring& inputws)
{
return WChar2Ansi(inputws.c_str());
}
//Converting a Ansi string to WChar string
std::wstring Ansi2WChar(LPCSTR pszSrc, int nLen)
{
int nSize = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, 0, 0);
if(nSize <= 0) return NULL;
WCHAR *pwszDst = new WCHAR[nSize+1];
if( NULL == pwszDst) return NULL;
MultiByteToWideChar(CP_ACP, 0,(LPCSTR)pszSrc, nLen, pwszDst, nSize);
pwszDst[nSize] = 0;
if( pwszDst[0] == 0xFEFF) // skip Oxfeff
for(int i = 0; i < nSize; i ++)
pwszDst[i] = pwszDst[i+1];
wstring wcharString(pwszDst);
delete pwszDst;
return wcharString;
}
std::wstring s2ws(const string& s)
{
return Ansi2WChar(s.c_str(),s.size());
}
W二U方法:(x)采用ATL装_bstr_t的过渡:(x)Q注Q_bstr_是Microsoft Specific的,所以下面代码可以在VS2005通过Q无UL性)Q?/p>
#include <string>
#include <comutil.h>
using namespace std;
#pragma comment(lib, "comsuppw.lib")
string ws2s(const wstring& ws);
wstring s2ws(const string& s);
string ws2s(const wstring& ws)
{
_bstr_t t = ws.c_str();
char* pchar = (char*)t;
string result = pchar;
return result;
}
wstring s2ws(const string& s)
{
_bstr_t t = s.c_str();
wchar_t* pwchar = (wchar_t*)t;
wstring result = pwchar;
return result;
}
W三U方法:(x)使用CRT库的mbstowcs()函数和wcstombs()函数Q^台无养I需讑֮locale?/p>
#include <string>
#include <locale.h>
using namespace std;
string ws2s(const wstring& ws)
{
string curLocale = setlocale(LC_ALL, NULL); // curLocale = "C";
setlocale(LC_ALL, "chs");
const wchar_t* _Source = ws.c_str();
size_t _Dsize = 2 * ws.size() + 1;
char *_Dest = new char[_Dsize];
memset(_Dest,0,_Dsize);
wcstombs(_Dest,_Source,_Dsize);
string result = _Dest;
delete []_Dest;
setlocale(LC_ALL, curLocale.c_str());
return result;
}
wstring s2ws(const string& s)
{
setlocale(LC_ALL, "chs");
const char* _Source = s.c_str();
size_t _Dsize = s.size() + 1;
wchar_t *_Dest = new wchar_t[_Dsize];
wmemset(_Dest, 0, _Dsize);
mbstowcs(_Dest,_Source,_Dsize);
wstring result = _Dest;
delete []_Dest;
setlocale(LC_ALL, "C");
return result;
}
?utf8.utf16.utf32的相互{?/p>
可以参考Unicode.org 上有ConvertUTF.c和ConvertUTF.h Q下载地址Q?a >http://www.unicode.org/Public/PROGRAMS/CVTUTF/Q?/p>
实现文gConvertUTF.cQ(.h省)
/**//*
* Copyright 2001-2004 Unicode, Inc.
*
* Disclaimer
*
* This source code is provided as is by Unicode, Inc. No claims are
* made as to fitness for any particular purpose. No warranties of any
* kind are expressed or implied. The recipient agrees to determine
* applicability of information provided. If this file has been
* purchased on magnetic or optical media from Unicode, Inc., the
* sole remedy for any claim will be exchange of defective media
* within 90 days of receipt.
*
* Limitations on Rights to Redistribute This Code
*
* Unicode, Inc. hereby grants the right to freely use the information
* supplied in this file in the creation of products supporting the
* Unicode Standard, and to make copies of this file in any form
* for internal or external distribution as long as this notice
* remains attached.
*/
/**//* ---------------------------------------------------------------------
Conversions between UTF32, UTF-16, and UTF-8. Source code file.
Author: Mark E. Davis, 1994.
Rev History: Rick McGowan, fixes & updates May 2001.
Sept 2001: fixed const & error conditions per
mods suggested by S. Parent & A. Lillich.
June 2002: Tim Dodd added detection and handling of incomplete
source sequences, enhanced error detection, added casts
to eliminate compiler warnings.
July 2003: slight mods to back out aggressive FFFE detection.
Jan 2004: updated switches in from-UTF8 conversions.
Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions.
See the header file "ConvertUTF.h" for complete documentation.
------------------------------------------------------------------------ */
#include "ConvertUTF.h"
#ifdef CVTUTF_DEBUG
#include <stdio.h>
#endif
static const int halfShift = 10; /**//* used for shifting by 10 bits */
static const UTF32 halfBase = 0x0010000UL;
static const UTF32 halfMask = 0x3FFUL;
#define UNI_SUR_HIGH_START (UTF32)0xD800
#define UNI_SUR_HIGH_END (UTF32)0xDBFF
#define UNI_SUR_LOW_START (UTF32)0xDC00
#define UNI_SUR_LOW_END (UTF32)0xDFFF
#define false 0
#define true 1
/**//* --------------------------------------------------------------------- */
ConversionResult ConvertUTF32toUTF16 (
const UTF32** sourceStart, const UTF32* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF32* source = *sourceStart;
UTF16* target = *targetStart;
while (source < sourceEnd) {
UTF32 ch;
if (target >= targetEnd) {
result = targetExhausted; break;
}
ch = *source++;
if (ch <= UNI_MAX_BMP) { /**//* Target is a character <= 0xFFFF */
/**//* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
if (flags == strictConversion) {
--source; /**//* return to the illegal value itself */
result = sourceIllegal;
break;
} else {
*target++ = UNI_REPLACEMENT_CHAR;
}
} else {
*target++ = (UTF16)ch; /**//* normal case */
}
} else if (ch > UNI_MAX_LEGAL_UTF32) {
if (flags == strictConversion) {
result = sourceIllegal;
} else {
*target++ = UNI_REPLACEMENT_CHAR;
}
} else {
/**//* target is a character in range 0xFFFF - 0x10FFFF. */
if (target + 1 >= targetEnd) {
--source; /**//* Back up source pointer! */
result = targetExhausted; break;
}
ch -= halfBase;
*target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
*target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
}
}
*sourceStart = source;
*targetStart = target;
return result;
}
/**//* --------------------------------------------------------------------- */
ConversionResult ConvertUTF16toUTF32 (
const UTF16** sourceStart, const UTF16* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF16* source = *sourceStart;
UTF32* target = *targetStart;
UTF32 ch, ch2;
while (source < sourceEnd) {
const UTF16* oldSource = source; /**//* In case we have to back up because of target overflow. */
ch = *source++;
/**//* If we have a surrogate pair, convert to UTF32 first. */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
/**//* If the 16 bits following the high surrogate are in the source buffer */
if (source < sourceEnd) {
ch2 = *source;
/**//* If it's a low surrogate, convert to UTF32. */
if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+ (ch2 - UNI_SUR_LOW_START) + halfBase;
++source;
} else if (flags == strictConversion) { /**//* it's an unpaired high surrogate */
--source; /**//* return to the illegal value itself */
result = sourceIllegal;
break;
}
} else { /**//* We don't have the 16 bits following the high surrogate. */
--source; /**//* return to the high surrogate */
result = sourceExhausted;
break;
}
} else if (flags == strictConversion) {
/**//* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
--source; /**//* return to the illegal value itself */
result = sourceIllegal;
break;
}
}
if (target >= targetEnd) {
source = oldSource; /**//* Back up source pointer! */
result = targetExhausted; break;
}
*target++ = ch;
}
*sourceStart = source;
*targetStart = target;
#ifdef CVTUTF_DEBUG
if (result == sourceIllegal) {
fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2);
fflush(stderr);
}
#endif
return result;
}
/**//* --------------------------------------------------------------------- */
/**//*
* Index into the table below with the first byte of a UTF-8 sequence to
* get the number of trailing bytes that are supposed to follow it.
* Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is
* left as-is for anyone who may want to do such conversion, which was
* allowed in earlier algorithms.
*/
static const char trailingBytesForUTF8[256] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
};
/**//*
* Magic values subtracted from a buffer value during UTF8 conversion.
* This table contains as many values as there might be trailing bytes
* in a UTF-8 sequence.
*/
static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
0x03C82080UL, 0xFA082080UL, 0x82082080UL };
/**//*
* Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
* into the first byte, depending on how many bytes follow. There are
* as many entries in this table as there are UTF-8 sequence types.
* (I.e., one byte sequence, two byte etc.). Remember that sequencs
* for *legal* UTF-8 will be 4 or fewer bytes total.
*/
static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
/**//* --------------------------------------------------------------------- */
/**//* The interface converts a whole buffer to avoid function-call overhead.
* Constants have been gathered. Loops & conditionals have been removed as
* much as possible for efficiency, in favor of drop-through switches.
* (See "Note A" at the bottom of the file for equivalent code.)
* If your compiler supports it, the "isLegalUTF8" call can be turned
* into an inline function.
*/
/**//* --------------------------------------------------------------------- */
ConversionResult ConvertUTF16toUTF8 (
const UTF16** sourceStart, const UTF16* sourceEnd,
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF16* source = *sourceStart;
UTF8* target = *targetStart;
while (source < sourceEnd) {
UTF32 ch;
unsigned short bytesToWrite = 0;
const UTF32 byteMask = 0xBF;
const UTF32 byteMark = 0x80;
const UTF16* oldSource = source; /**//* In case we have to back up because of target overflow. */
ch = *source++;
/**//* If we have a surrogate pair, convert to UTF32 first. */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
/**//* If the 16 bits following the high surrogate are in the source buffer */
if (source < sourceEnd) {
UTF32 ch2 = *source;
/**//* If it's a low surrogate, convert to UTF32. */
if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+ (ch2 - UNI_SUR_LOW_START) + halfBase;
++source;
} else if (flags == strictConversion) { /**//* it's an unpaired high surrogate */
--source; /**//* return to the illegal value itself */
result = sourceIllegal;
break;
}
} else { /**//* We don't have the 16 bits following the high surrogate. */
--source; /**//* return to the high surrogate */
result = sourceExhausted;
break;
}
} else if (flags == strictConversion) {
/**//* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
--source; /**//* return to the illegal value itself */
result = sourceIllegal;
break;
}
}
/**//* Figure out how many bytes the result will require */
if (ch < (UTF32)0x80) { bytesToWrite = 1;
} else if (ch < (UTF32)0x800) { bytesToWrite = 2;
} else if (ch < (UTF32)0x10000) { bytesToWrite = 3;
} else if (ch < (UTF32)0x110000) { bytesToWrite = 4;
} else { bytesToWrite = 3;
ch = UNI_REPLACEMENT_CHAR;
}
target += bytesToWrite;
if (target > targetEnd) {
source = oldSource; /**//* Back up source pointer! */
target -= bytesToWrite; result = targetExhausted; break;
}
switch (bytesToWrite) { /**//* note: everything falls through. */
case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]);
}
target += bytesToWrite;
}
*sourceStart = source;
*targetStart = target;
return result;
}
/**//* --------------------------------------------------------------------- */
/**//*
* Utility routine to tell whether a sequence of bytes is legal UTF-8.
* This must be called with the length pre-determined by the first byte.
* If not calling this from ConvertUTF8to*, then the length can be set by:
* length = trailingBytesForUTF8[*source]+1;
* and the sequence is illegal right away if there aren't that many bytes
* available.
* If presented with a length > 4, this returns false. The Unicode
* definition of UTF-8 goes up to 4-byte sequences.
*/
static Boolean isLegalUTF8(const UTF8 *source, int length) {
UTF8 a;
const UTF8 *srcptr = source+length;
switch (length) {
default: return false;
/**//* Everything else falls through when "true" */
case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
case 2: if ((a = (*--srcptr)) > 0xBF) return false;
switch (*source) {
/**//* no fall-through in this inner switch */
case 0xE0: if (a < 0xA0) return false; break;
case 0xED: if (a > 0x9F) return false; break;
case 0xF0: if (a < 0x90) return false; break;
case 0xF4: if (a > 0x8F) return false; break;
default: if (a < 0x80) return false;
}
case 1: if (*source >= 0x80 && *source < 0xC2) return false;
}
if (*source > 0xF4) return false;
return true;
}
/**//* --------------------------------------------------------------------- */
/**//*
* Exported function to return whether a UTF-8 sequence is legal or not.
* This is not used here; it's just exported.
*/
Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) {
int length = trailingBytesForUTF8[*source]+1;
if (source+length > sourceEnd) {
return false;
}
return isLegalUTF8(source, length);
}
/**//* --------------------------------------------------------------------- */
ConversionResult ConvertUTF8toUTF16 (
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF8* source = *sourceStart;
UTF16* target = *targetStart;
while (source < sourceEnd) {
UTF32 ch = 0;
unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
if (source + extraBytesToRead >= sourceEnd) {
result = sourceExhausted; break;
}
/**//* Do this check whether lenient or strict */
if (! isLegalUTF8(source, extraBytesToRead+1)) {
result = sourceIllegal;
break;
}
/**//*
* The cases all fall through. See "Note A" below.
*/
switch (extraBytesToRead) {
case 5: ch += *source++; ch <<= 6; /**//* remember, illegal UTF-8 */
case 4: ch += *source++; ch <<= 6; /**//* remember, illegal UTF-8 */
case 3: ch += *source++; ch <<= 6;
case 2: ch += *source++; ch <<= 6;
case 1: ch += *source++; ch <<= 6;
case 0: ch += *source++;
}
ch -= offsetsFromUTF8[extraBytesToRead];
if (target >= targetEnd) {
source -= (extraBytesToRead+1); /**//* Back up source pointer! */
result = targetExhausted; break;
}
if (ch <= UNI_MAX_BMP) { /**//* Target is a character <= 0xFFFF */
/**//* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
if (flags == strictConversion) {
source -= (extraBytesToRead+1); /**//* return to the illegal value itself */
result = sourceIllegal;
break;
} else {
*target++ = UNI_REPLACEMENT_CHAR;
}
} else {
*target++ = (UTF16)ch; /**//* normal case */
}
} else if (ch > UNI_MAX_UTF16) {
if (flags == strictConversion) {
result = sourceIllegal;
source -= (extraBytesToRead+1); /**//* return to the start */
break; /**//* Bail out; shouldn't continue */
} else {
*target++ = UNI_REPLACEMENT_CHAR;
}
} else {
/**//* target is a character in range 0xFFFF - 0x10FFFF. */
if (target + 1 >= targetEnd) {
source -= (extraBytesToRead+1); /**//* Back up source pointer! */
result = targetExhausted; break;
}
ch -= halfBase;
*target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
*target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
}
}
*sourceStart = source;
*targetStart = target;
return result;
}
/**//* --------------------------------------------------------------------- */
ConversionResult ConvertUTF32toUTF8 (
const UTF32** sourceStart, const UTF32* sourceEnd,
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF32* source = *sourceStart;
UTF8* target = *targetStart;
while (source < sourceEnd) {
UTF32 ch;
unsigned short bytesToWrite = 0;
const UTF32 byteMask = 0xBF;
const UTF32 byteMark = 0x80;
ch = *source++;
if (flags == strictConversion ) {
/**//* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
--source; /**//* return to the illegal value itself */
result = sourceIllegal;
break;
}
}
/**//*
* Figure out how many bytes the result will require. Turn any
* illegally large UTF32 things (> Plane 17) into replacement chars.
*/
if (ch < (UTF32)0x80) { bytesToWrite = 1;
} else if (ch < (UTF32)0x800) { bytesToWrite = 2;
} else if (ch < (UTF32)0x10000) { bytesToWrite = 3;
} else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4;
} else { bytesToWrite = 3;
ch = UNI_REPLACEMENT_CHAR;
result = sourceIllegal;
}
target += bytesToWrite;
if (target > targetEnd) {
--source; /**//* Back up source pointer! */
target -= bytesToWrite; result = targetExhausted; break;
}
switch (bytesToWrite) { /**//* note: everything falls through. */
case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]);
}
target += bytesToWrite;
}
*sourceStart = source;
*targetStart = target;
return result;
}
/**//* --------------------------------------------------------------------- */
ConversionResult ConvertUTF8toUTF32 (
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF8* source = *sourceStart;
UTF32* target = *targetStart;
while (source < sourceEnd) {
UTF32 ch = 0;
unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
if (source + extraBytesToRead >= sourceEnd) {
result = sourceExhausted; break;
}
/**//* Do this check whether lenient or strict */
if (! isLegalUTF8(source, extraBytesToRead+1)) {
result = sourceIllegal;
break;
}
/**//*
* The cases all fall through. See "Note A" below.
*/
switch (extraBytesToRead) {
case 5: ch += *source++; ch <<= 6;
case 4: ch += *source++; ch <<= 6;
case 3: ch += *source++; ch <<= 6;
case 2: ch += *source++; ch <<= 6;
case 1: ch += *source++; ch <<= 6;
case 0: ch += *source++;
}
ch -= offsetsFromUTF8[extraBytesToRead];
if (target >= targetEnd) {
source -= (extraBytesToRead+1); /**//* Back up the source pointer! */
result = targetExhausted; break;
}
if (ch <= UNI_MAX_LEGAL_UTF32) {
/**//*
* UTF-16 surrogate values are illegal in UTF-32, and anything
* over Plane 17 (> 0x10FFFF) is illegal.
*/
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
if (flags == strictConversion) {
source -= (extraBytesToRead+1); /**//* return to the illegal value itself */
result = sourceIllegal;
break;
} else {
*target++ = UNI_REPLACEMENT_CHAR;
}
} else {
*target++ = ch;
}
} else { /**//* i.e., ch > UNI_MAX_LEGAL_UTF32 */
result = sourceIllegal;
*target++ = UNI_REPLACEMENT_CHAR;
}
}
*sourceStart = source;
*targetStart = target;
return result;
}
/**//* ---------------------------------------------------------------------
Note A.
The fall-through switches in UTF-8 reading code save a
temp variable, some decrements & conditionals. The switches
are equivalent to the following loop:
{
int tmpBytesToRead = extraBytesToRead+1;
do {
ch += *source++;
--tmpBytesToRead;
if (tmpBytesToRead) ch <<= 6;
} while (tmpBytesToRead > 0);
}
In UTF-8 writing code, the switches on "bytesToWrite" are
similarly unrolled loops.
--------------------------------------------------------------------- */
?C++ 的字W串与C#的{?/p>
1Q将system::String 转化为C++的stringQ?br>// convert_system_string.cpp
// compile with: /clr
#include <string>
#include <iostream>
using namespace std;
using namespace System;
void MarshalString ( String ^ s, string& os ) {
using namespace Runtime::InteropServices;
const char* chars =
(const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
os = chars;
Marshal::FreeHGlobal(IntPtr((void*)chars));
}
void MarshalString ( String ^ s, wstring& os ) {
using namespace Runtime::InteropServices;
const wchar_t* chars =
(const wchar_t*)(Marshal::StringToHGlobalUni(s)).ToPointer();
os = chars;
Marshal::FreeHGlobal(IntPtr((void*)chars));
}
int main() {
string a = "test";
wstring b = L"test2";
String ^ c = gcnew String("abcd");
cout << a << endl;
MarshalString(c, a);
c = "efgh";
MarshalString(c, b);
cout << a << endl;
wcout << b << endl;
}
2Q将System::String转化为char*或w_char*
// convert_string_to_wchar.cpp
// compile with: /clr
#include < stdio.h >
#include < stdlib.h >
#include < vcclr.h >
using namespace System;
int main() {
String ^str = "Hello";
// Pin memory so GC can't move it while native function is called
pin_ptr<const wchar_t> wch = PtrToStringChars(str);
printf_s("%S\n", wch);
// Conversion to char* :
// Can just convert wchar_t* to char* using one of the
// conversion functions such as:
// WideCharToMultiByte()
// wcstombs_s()
// etc
size_t convertedChars = 0;
size_t sizeInBytes = ((str->Length + 1) * 2);
errno_t err = 0;
char *ch = (char *)malloc(sizeInBytes);
err = wcstombs_s(&convertedChars,
ch, sizeInBytes,
wch, sizeInBytes);
if (err != 0)
printf_s("wcstombs_s failed!\n");
printf_s("%s\n", ch);
}
二、在Linux下如何用Y盘、光盘以?qing)DOS{非Linux分区
装蝲的命令是mountQ格式如下:(x)mount -t 文gpȝcd 讑֤?装蝲目录
文gpȝcd是分区格式QLinux支持的文件系l类型有许多Q?/p>
msdos DOS分区文gpȝcd
vfat 支持长文件名的DOS分区文gQ可以理解ؓ(f)Windows文gQ系l类?br> iso9660 光盘的文件系l类?br> ext2 Linux的文件系l类?/p>
讑֤名,指的是你要装载的讑֤的名U。Y盘一般ؓ(f)/dev/fd0 fd1Q光盘则Ҏ(gu)你的光驱的位|来军_Q通常光驱装在W二盘的主盘位|就?dev/hdc;如果讉K的是DOS的分区,则列出其讑֤名,?dev/hda1是指W一盘的第一个分区?装蝲目录Q就是你指定讑֤的蝲入点?/p>
1. 装蝲软盘
首先用mkdir /mnt/floppy ?mnt目录下徏立一个空的floppy目录Q然后输入mount -t msdos /dev/fd0 /mnt/floppy DOS文g格式的一张Y盘装载进来,以后可以在/mnt/floppy目录下找到这张Y盘的所有内宏V?/p>
2. 装蝲Windows所在的C?/p>
mkdir /mnt/c ?mnt目录下徏立一个空的c目录;
mount -t vfat /dev/hda1 /mnt/c Windows的C盘按长文件名格式装蝲?mnt/c目录下,以后在该目录下就能读写C(j)盘根目录中的内容?/p>
3.装蝲光盘
mkdir /mnt/cdrom ?mnt目录下徏立一个空的cdrom目录;
mount -t iso9660 /dev/hdc /mnt/cdrom 光盘蝲入到文gpȝ中来Q将?mnt/cdrom目录下找到光盘内宏V有的Linux版本允许用mount /dev/cdrom或mount /mnt/cdrom命o(h)装蝲光盘?br> 要注意的是,用mount命o(h)装入的是软盘、光盘,而不是Y驱、光驱。有些初学者容易犯一个毛病,以ؓ(f)用上面命令后QY驱就成了/mnt/floppyQ光驱就成了/mnt/cdromQ其实不Ӟ当你要换一张光盘或软盘Ӟ一定要先卸载,再对新盘重新装蝲?/p>
4.卸蝲
卸蝲的命令格式是:umonut 目录名,例如要卸载Y盘,可输入命令umonut /mnt/floppy。要注意的是Q在卸蝲光盘之前Q直接按光驱面板上的弹出键是不会(x)起作用的?/p>
三、RPM的用方?/p>
1. 用RPM安装软g?Qrpm -ivh 软g文g?br> 例如 rpm -ivh fvwm95-2.0.43a.chinese-1.i386.rpm 屏幕上就?x)输软g包的名称和安装的q度?
fvwm95 ###############
当进度条走到底,中文fvwm95Q一UX-Window的界面)安装完了,再运行X-WindowQ啊Q全中文的fvwm95在我的眼前?/p>
2. 用RPM反安装Y件包:rpm -e 软g?br> 例如:rpm -e fvwm95
3. 用RPM升软g?rpm -Uvh 软g升版文件名
例如:rpm -Uvh fvwm95-2.1.0a.chinese-1.i386.rpmQRPM自动反安装原来的老版本,升U版的Y件安装入pȝ?/p>
四、Linux开机直接进入文本界面,怎样才能让它默认q入囑Ş界面Q?/p>
修改/etc/inittab文gQ其中有一行id:3:initdefaultQ意思是说开机默认进入运行?Q多用户的文本界面)Q把它改成id:5:initdefaultQ既开机默认进入运行?Q多用户的图形界面)。这样就行了?/p>
五、如何将man转存为文本文Ӟ
以ls的manZ
man ls |col -b >ls.txt
info变成文本,以makeZ
info make -o make.txt -s
六、如何将?man page 转成 HTML 格式Q?/p>
使用 man2html q个指o(h)Q就可以?man page 转成 HTML 格式了。用法是Q?/p>
man2html filename > htmlfile.html
七?tarQ?tar.gzQ?bz2Q?tar.bz2Q?bzQ?gz是什么文Ӟ如何解开他们Q?br>他们都是文g(压羃)包?br>.tarQ把文g打包Q不压羃Qtar cvf *.tar dirName 解开Qtar xvf *.tar
.tar.gzQ把文g打包q压~:(x)tar czvf *.tar.gz dirName 解开Qtar xzvf *.tar.gz
.bz2Q解开Qbzip2 -d *.bz2
.bzQ解开Qbzip -d *.bz
.gzQ解开Qgzip -d *.gz
八、linux下如何解开.zipQ?rar压羃文gQ?br>rh8下有一个图形界面的软gfile-roller可以做这件事。o(h)外可以用unzip *.zip解开zip文gQunrar *.rar解开rar文gQ不qunrar一般系l不自带Q要到网上下载?/p>
?ji)、linux下如何浏?iso光盘镜像文gQ?br>a.Z个目录,如:(x)mkdir a
b.把iso文g挂蝲到该目录上:(x)mount -o loop xxxx.iso a
现在目录a里的内容是iso文g里的内容了?/p>
十、linux下如何配|网l?
用netconfig?#8220;IP address:”是要配|的IP地址Q?#8220;Netmask:”子网掩码Q?#8220;Default gateway (IP):”|关Q?#8220;Primary nameserver:”DNS服务器IP
十一、如何让linux启动后自动挂载制定分区?
~辑/etc/fstab文gQ在里面加入相应的行
十二、如何定制linux启动时启动的服务Q?br>在控制台或终端下q行ntsysvQ然后把要启动的服务选上Q如果要开Z启动某个那就把他的选中L?/p>
十三、删除文件大ؓ(f)零的文g
rm -i `find ./ -size 0`
find ./ -size 0 -exec rm {} \;
find ./ -size |xargs rm -f &非常有效
for file in * #自己定义需要删除的文gcd
do
if [ ! -s ${file} ]
then
rm ${file}
echo “rm $file Success!”
fi
done
十四、查看系l信?br>cat /proc/cpuinfo - CPU (i.e. vendor, Mhz, flags like mmx)
cat /proc/interrupts - 中断
cat /proc/ioports - 讑֤IO端口
cat /proc/meminfo - 内存信息(i.e. mem used, free, swap size)
cat /proc/partitions - 所有设备的所有分?br>cat /proc/pci - PCI讑֤的信?br>cat /proc/swaps - 所有Swap分区的信?br>cat /proc/version - Linux的版本号 相当?uname -r
uname -a - 看系l内核等信息
十五、cd光盘做成iso文g
cp /dev/cdrom xxxx.iso
十六、快速观看开机的g(g)?br>dmesg | more
十七、查看硬盘的使用情况
df -k 以K为单位显C?br>df -h 以h性化单位昄Q可以是b,k,m,g,t..
十八、查看目录的大小
du -sh dirname
-s 仅显C总计
-h 以K、M、G为单位,提高信息的可L。KB、MB、GB是以1024为换单位,-H?000为换单位?/p>
十九(ji)、查找或删除正在使用某文件的q程
fuser filename
fuser -k filename
二十、字W模式下讄/删除环境变量
bash?br>讄Qexport 变量?变量?br>删除Qunset 变量?br>csh?br>讄Qsetenv 变量?变量?br>删除Qunsetenv 变量?/p>
二十一、vim中显C颜色或不显C颜?br>vi ~/.vimrc; 如果有syntax onQ则昄颜色Qsyntax offQ则不显C颜?/p>
二十二、修改系l时?br>date -s “2003-04-14 cst”Qcst指时区,旉讑֮用date -s 18:10
二十三、开机就mount上windows下的分区
自动windows的d盘挂?mnt/d上,用vi打开/etc/fstabQ加入以下一?br>/dev/hda5 /mnt/d vfat defaults,codepage=936,iocharset=cp936 0 0
注意Q先得手工徏立一?mnt/d目录
二十四、在多目录中查找某个文件的Ҏ(gu)
find /dir -name filename.ext
du -a | grep filename.ext
locate filename.ext
二十五、不让普通用戯己改密码
[root@xin_fc etc]# chmod 511 /usr/bin/passwd
又想让普通用戯己改密码
[root@xin_fc etc]# chmod 4511 /usr/bin/passwd
二十六、用dd做iso
dd if=/dev/cdrom of=/tmp/aaa.iso
二十七、让Linux自动同步旉
vi /etc/crontab
加上一?br>00 0 1 * * root rdate -s time.nist.gov
二十八、ssh上来能不能不自动断线
那是timetou的设|,修改TMOUT变量?/p>
二十?ji)、监视所有通过本机|卡的数?br>tcpdump iptraf
更改 WSAD 安装目录?wsappdev.ini 在行 VMArgs=-Xj9 后加入,为空则与操作pȝ默认语言相同?br>VMArgs=-Xj9 -Duser.language=en -Duser.region=US
其他语言参数Q?br>-Duser.language=en -Duser.region=US 【英文?br>-Duser.language=zh -Duser.region=CN 【中文简体?br>-Duser.language=zh -Duser.region=TW 【中文繁体?br>
在默认情况下QW(xu)ebSphere Application Developer 5在启动的时候会(x)弹出一个提C窗口让用户选择 workspace。如果,用户选中了窗口下方的“此工作I间用作~省值ƈ且不再显C此对话?#8221;Q那么下一ơ客户再q行W(xu)SAD的时候将不会(x)弹出提示H口让用户选择工作区。如果,用户再想更换工作区将无法q行。在 Eclipse 3.1 中,File 菜单下有 Switch Workspace 的选项Q但?WSAD 5 是基?Eclipse 2.x 的,我尝试了很久都没有找到在选项中更?workspace 的地斏V之后在|上(g)索,查到q个问题有如下解x案:(x) 1. 打开命o(h)行窗口,q入wsappdev.exe所在的目录(wsappdev.exe应该在WSAD的安装\径下) 2. 执行命o(h)Qwsappdev.exe -data Ҏ(gu)二:(x)用命令行方式启动q弹出提C窗口让用户选择工作?/p>
1. 打开命o(h)行窗口,q入wsappdev.exe所在的目录 2. 执行命o(h)Qwsappdev.exe -setworkspace Ҏ(gu)三:(x)通过更改配置文g让WSAD启动的时候弹Z个提C窗口让用户选择工作?/p>
1. 用文本编辑器打开wsappdev.ini文g(wsappdev.ini文g和wsappdev.exe文g在相同的路径?,默认情况下可以看到类似如下的内容Q?/p>
[Settings] DefaultWorkspace= ProductName=IBM WebSphere Studio Application Developer Version=5.1.1 Full=Yes KeyName=wsappdev510 VMArgs=-Xj9 LUMProductID=1 LUMProductVersion=5.1.1 Website=www.ibm.com/websphere/developer/zones/studio/appdev/ [Environment Variables] 2. ?[Environment Variables] 的上Ҏ(gu)加一?SetWorkSpace=true Q保?wsappdev.ini 文g?/p>
3. 关闭 wsappdev.ini 文gQ通过菜单或者直接双?wsappdev.exe 文g再次启动 WSAD 的时候,׃(x)弹出一个提C窗口让用户选择工作区?/p>
○在 eclipse 的快h式后面加一?参数:-nl “zh_US”,可以找回英文的界面Q加参数Q?nl “zh_CN” Q就可以用到中文界面
Ҏ(gu)一Q用命o(h)行方式启动ƈ指定所用的工作?/p>
AWK是一U优良的文本处理工具。它不仅?Linux 中也是Q何环境中现有的功能最强大的数据处理发动机之一。这U编E及(qing)数据操作语言Q其名称得自于它的创始h Alfred Aho 、Peter Weinberger ?Brian Kernighan 姓氏的首个字母)的最大功能取决于一个h所拥有的知识?AWK 提供了极其强大的功能Q可以进行样式装入、流控制、数学运符、进E控制语句甚至于内置的变量和函数。它具备了一个完整的语言所应具有的几乎所有精特性。实际上 AWK 的确拥有自己的语aQ?AWK E序设计语言Q三位创已它正式定义?#8220;样式扫描和处理语a”。它允许(zhn)创建简短的E序Q这些程序读取输入文件、ؓ(f)数据排序、处理数据、对输入执行计算以及(qing)生成报表Q还有无数其他的功能?/p>
你可能对UNIX比较熟?zhn)Q但你可能对awk很陌生,q一点也不奇怪,的确Q与其优U的功能相比,awkq远没达到它应有的知名度。awk是什么?与其它大多数UNIX命o(h)不同的是Q从名字上看Q我们不可能知道awk的功能:(x)它既不是h独立意义的英文单词,也不是几个相兛_词的~写。事实上Qawk是三个h名的~写Q他们是QAho?Peter)Weinberg?(Brain)Kernighan。正是这三个人创造了awk—一个优U的样式扫描与处理工具?/p>
最单地_(d) AWK 是一U用于处理文本的~程语言工具。AWK 在很多方面类g shell ~程语言Q尽?AWK h完全属于其本w的语法。它的设计思想来源?SNOBOL4 、sed 、Marc Rochkind设计的有效性语a、语a工具 yacc ?lex Q当然还?C 语言中获取了一些优U的思想。在最初创?AWK Ӟ其目的是用于文本处理Qƈ且这U语a的基是,只要在输入数据中有模式匹配,执行一pd指o(h)。该实用工具扫描文g中的每一行,查找与命令行中所l定内容相匹配的模式。如果发现匹配内容,则进行下一个编E步骤。如果找不到匚w内容Q则l箋处理下一行?/p>
管操作可能?x)很复杂Q但命o(h)的语法始l是Q?/p>
awk ‘{pattern + action}’ {filenames}
其中 pattern 表示 AWK 在数据中查找的内容,?action 是在扑ֈ匚w内容时所执行的一pd命o(h)。花括号 ({}) 不需要在E序中始l出玎ͼ但它们用于根据特定的模式对一pd指o(h)q行分组?/p>
gawk ?AWK ?GNU 版本?/p>
一、AWK的功能是什么?
与sed?grep很相|awk是一U样式扫描与处理工具。但其功能却大大Zsed和grep。awk提供了极其强大的功能Q它几乎可以完成grep和sed所能完成的全部工作Q同Ӟ它还可以可以q行样式装入、流控制、数学运符、进E控制语句甚至于内置的变量和函数。它具备了一个完整的语言所应具有的几乎所有精特性。实际上Qawk的确拥有自己的语aQawkE序设计语言Qawk的三位创已它正式定义为:(x)样式扫描和处理语a?/p>
二、ؓ(f)什么用awk?
即如此Q你也许仍然?x)问Q我Z么要使用awk?
使用awk的第一个理由是Z文本的样式扫描和处理是我们经常做的工作,awk所做的工作有些象数据库Q但与数据库不同的是Q它处理的是文本文gQ这些文件没有专门的存储格式Q普通的Zp~辑、阅诅R理解和处理它们。而数据库文g往往hҎ(gu)的存储格式,q得它们必ȝ数据库处理程序来处理它们。既然这U类g数据库的处理工作我们l常?x)遇刎ͼ我们应当找到处理它们的便易行的Ҏ(gu)QUNIX有很多这斚w的工P例如sed 、grep、sort以及(qing)find{等Qawk是其中十分优U的一U?/p>
使用awk的第二个理由是awk是一个简单的工具Q当然这是相对于其强大的功能来说的。的,UNIX有许多优U的工P例如UNIX天然的开发工具C语言?qing)其延箋C++非常的优秀。但相对于它们来_(d)awk完成同样的功能要方便和简捷得多。这首先是因为awk提供了适应多种需要的解决Ҏ(gu)Q从解决单问题的awk命o(h)行到复杂而精巧的awkE序设计语言Q这样做的好处是Q你可以不必用复杂的Ҏ(gu)去解x来很单的问题。例如,你可以用一个命令行解决单的问题Q而C不行Q即使一个再单的E序QC语言也必ȝq编写、编译的全过E。其ơ,awk本n是解释执行的Q这׃得awkE序不必l过~译的过E,同时Q这也得它与shell scriptE序能够很好的契合。最后,awk本n较C语言单,虽然awk吸收了C语言很多优秀的成分,熟?zhn)C语言?x)对学?fn)awk有很大的帮助Q但 awk本n不须要会(x)使用C语言——一U功能强大但需要大量时间学?fn)才能掌握其技巧的开发工兗?/p>
使用awk的第三个理由是awk是一个容易获得的工具。与C和C++语言不同Qawk只有一个文?/bin/awk)Q而且几乎每个版本的UNIX都提供各自版本的awkQ你完全不必费心L如何获得awk。但C语言却不是这P虽然C语言是UNIX天然的开发工P但这个开发工具却是单独发行的Q换a之,你必Mؓ(f)你的UNIX版本的C语言开发工具单独付费(当然使用D版者除外)Q获得ƈ安装它,然后你才可以使用它?/p>
Z以上理由Q再加上awk强大的功能,我们有理pQ如果你要处理与文本样式扫描相关的工作,awk应该是你的第一选择。在q里有一个可遵@的一般原则:(x)如果你用普通的shell工具或shell script有困隄话,试试awk,如果awk仍不能解决问题,则便用C语言Q如果C语言仍然p|Q则U至C++?/p>
三、awk的调用方?/p>
前面曄说过Qawk提供了适应多种需要的不同解决Ҏ(gu)Q它们是Q?/p>
1?awk命o(h)行,你可以象使用普通UNIX命o(h)一样用awkQ在命o(h)行中你也可以使用awkE序设计语言Q虽然awk支持多行的录入,但是录入镉K的命令行q保证其正确无误却是一件o(h)人头疼的事,因此Q这U方法一般只用于解决单的问题。当Ӟ你也可以在shell scriptE序中引用awk命o(h)行甚至awkE序脚本?/p>
2、?f选项调用awkE序。awk允许一DawkE序写入一个文本文Ӟ然后在awk命o(h)行中?f选项调用q执行这D늨序。具体的Ҏ(gu)我们在后面的awk语法中讲到?/p>
3、利用命令解释器调用awkE序Q利用UNIX支持的命令解释器功能Q我们可以将一DawkE序写入文本文gQ然后在它的W一行加?
#!/bin/awk -f
q赋予这个文本文件以执行的权限。这样做之后Q你可以在命o(h)行中用类g下面q样的方式调用ƈ执行q段awkE序了?/p>
$awk脚本文本?待处理文?/p>
awk的语法:(x)
与其它UNIX命o(h)一Pawk拥有自己的语法:(x)
awk [ -F re] [parameter…] [’prog’] [-f progfile][in_file…]
参数说明Q?/p>
-F re:允许awk更改其字D分隔符?/p>
parameter: 该参数帮助ؓ(f)不同的变量赋倹{?/p>
‘prog’: awk的程序语句段。这个语句段必须用单拓号Q?#8217;?#8217;括vQ以防被shell解释。这个程序语句段的标准Ş式ؓ(f)Q?/p>
‘pattern {action}’
其中pattern参数可以是egrep正则表达式中的Q何一个,它可以用语?re/再加上一些样式匹配技巧构成。与sedcMQ你也可以?#8221;,”分开两样式以选择某个范围。关于匹配的l节Q你可以参考附录,如果仍不懂的话,找本UNIX书学学grep和sedQ本人是在学?fn)ed时掌握匹配技术的Q?action参数L被大括号包围Q它׃pȝawk语句l成Q各语句之间?#8221;;”分隔。awk解释它们Qƈ在patternl定的样式匹配的记录上执行其操作。与shellcMQ你也可以?#8220;#”作ؓ(f)注释W,它“#”到行内容成ؓ(f)注释Q在解释执行Ӟ它们被忽略。你可以省略pattern?action之一Q但不能两者同时省略,当省略pattern时没有样式匹配,表示Ҏ(gu)有行Q记录)均执行操作,省略action时执行缺省的操作——在标准输出上显C?/p>
-f progfile:允许awk调用q执行progfile指定有程序文件。progfile是一个文本文Ӟ他必ȝ合awk的语法?/p>
in_file:awk的输入文Ӟawk允许对多个输入文件进行处理。值得注意的是awk不修改输入文件。如果未指定输入文gQawk接受标准输入,q将l果昄在标准输Z。awk支持输入输出重定向?/p>
awk的记录、字D与内置变量Q?/p>
前面说过Qawk处理的工作与数据库的处理方式有相同之处,其相同处之一是awk支持对记录和字段的处理,其中对字D늚处理是grep和sed不能实现的,q也是awk优于二者的原因之一。在awk中,~省的情况下L文本文件中的一行视Z个记录,而将一行中的某一部分作ؓ(f)记录中的一个字Dc(din)ؓ(f)了操作这些不同的字段Qawk借用shell的方法,?1,$2,$3…q样的方式来序地表CQ记录)中的不同字段。特D地Qawk?0表示整个行(记录Q。不同的字段之间是用UC分隔W的字符分隔开的。系l默认的分隔W是I格。awk允许在命令行中用-F re的Ş式来改变q个分隔W。事实上Qawk用一个内|的变量FS来记忆这个分隔符。awk中有好几个这L(fng)内置变量Q例如,记录分隔W变量RS、当前工作的记录数NR{等Q本文后面的附表列出了全部的内置变量。这些内|的变量可以在awkE序中引用或修改Q例如,你可以利用NR变量在模式匹配中指定工作范围Q也可以通过修改记录分隔WRS让一个特D字W而不是换行符作ؓ(f)记录的分隔符?/p>
?昄文本文gmyfile中第七行到第十五行中以字W?分隔的第一字段Q第三字D和W七字段Q?/p>
awk -F % ‘NR==7,NR==15 {printf $1 $3 $7}’
四、awk的内|函?/p>
awk 之所以成ZU优U的程序设计语a的原因之一是它吸收了某些优U的程序设计语aQ例如CQ语a的许多优炏V这些优点之一是内置函数的用,awk定义q支持了一pd的内|函敎ͼ׃q些函数的用,使得awk提供的功能更为完善和强大Q例如,awk使用了一pd的字W串处理内置函数(q些函数看v来与C 语言的字W串处理函数怼Q其使用方式与C语言中的函数也相差无?Q正是由于这些内|函数的使用Qawk处理字符串的功能更加强大。本文后面的附录中列有一般的awk所提供的内|函敎ͼq些内置函数也许与你的awk版本有些出入Q因此,在用之前,最好参考一下你的系l中的联机帮助?/p>
作ؓ(f)内置函数的一个例子,我们在q里介绍awk的printf函数Q这个函C得awk与c语言的输出相一致。实际上Qawk中有许多引用形式都是从C语言借用q来的。如果你熟?zhn)C语言Q你也许?x)记得其中的printf函数Q它提供的强大格式输出功能曾l带我们许多的方ѝ幸q的是,我们在awk中又和它重逢了。awk中printf几乎与C语言中一模一P如果你熟(zhn)C语言的话Q你完全可以照C语言的模式用awk中的printf。因此在q里Q我们只l出一个例子,如果你不熟?zhn)的话Q请随便找一本C语言的入门书ȝ?/p>
?昄文gmyfile中的行号和第3字段Q?/p>
$awk ‘{printf”%03d%sn”,NR,$1}’ myfile
五、在命o(h)行用awk
按照序Q我们应当讲解awkE序设计的内容了Q但在讲解之前,我们用一些例子来对前面的知识q行回顾Q这些例子都是在命o(h)行中使用的,由此我们可以知道在命令行中用awk是多么的方便。这样做的原因一斚w是ؓ(f)下面的内容作铺垫Q另一斚w是介l一些解决简单问题的Ҏ(gu)Q我们完全没有必要用复杂的方法来解决单的问题?既然awk提供了较为简单的Ҏ(gu)的话?/p>
例:(x)昄文本文gmydoc匚wQ含有)字符?#8221;sun”的所有行?/p>
$awk ‘/sun/{print}’ mydoc
׃昄整个记录Q全行)是awk的缺省动作,因此可以省略actionV?/p>
$awk ‘/sun/’ mydoc
例:(x)下面是一个较为复杂的匚w的示例:(x)
$awk ‘/[Ss]un/,/[Mm]oon/ {print}’ myfile
它将昄W一个匹配Sun或sun的行与第一个匹配Moon或moon的行之间的行Qƈ昄到标准输Z?/p>
例:(x)下面的示例显CZ内置变量和内|函数l(f)engthQ)的用:(x)
$awk ‘length($0)>80 {print NR}’ myfile
该命令行显C文本myfile中所有超q?0个字W的行号Q在q里Q用$0表示整个记录Q行Q,同时Q内|变量NR不用标志符’$'?/p>
例:(x)作ؓ(f)一个较为实际的例子Q我们假设要对UNIX中的用户q行安全性检查,Ҏ(gu)是考察/etc下的passwd文gQ检查其中的passwd字段Q第二字D)是否?#8221;*”Q如不ؓ(f)”*”Q则表示该用h有设|密码,昄些用户名Q第一字段Q。我们可以用如下语句实现Q?/p>
#awk -F: ‘$2==”" {printf(”%s no password!n”,$1′ /etc/passwd
在这个示例中Qpasswd文g的字D分隔符?#8220;Q?#8221;Q因此,必须?FQ来更改默认的字D分隔符Q这个示例中也涉?qing)到了内|函数printf的用?/p>
六、awk的变?/p>
如同其它E序设计语言一Pawk允许在程序语a中设|变量,事实上,提供变量的功能是E序设计语言的其本要求,不提供变量的E序设计语言本hq从未见q?/p>
awk 提供两种变量Q一U是awk内置的变量,q前面我们已l讲q,需要着重指出的是,与后面提到的其它变量不同的是Q在awkE序中引用内|变量不需要用标志符”$”Q回忆一下前面讲q的NR的用)。awk提供的另一U变量是自定义变量。awk允许用户在awkE序语句中定义ƈ调用自已的变量。当然这U变量不能与内置变量?qing)其它awk保留字相同,在awk中引用自定义变量必须在它前面加上标志W?#8221;$”。与C语言不同的是Qawk中不需要对变量q行初始化, awkҎ(gu)其在awk中第一ơ出现的形式和上下文定其具体的数据cd。当变量cd不确定时Qawk默认其ؓ(f)字符串类型。这里有一个技巧:(x)如果你要让你?awkE序知道你所使用的变量的明确cdQ你应当在在E序中给它赋初倹{在后面的实例中Q我们将用到q一技巧?/p>
七、运与判断
作ؓ(f)一U程序设计语a所应具有的特点之一Qawk支持多种q算Q这些运与C语言提供的几本相同:(x)?????{等Q同Ӟawk也支持C语言中类?+?#8211;?=?=?+?-之类的功能,q给熟?zhn)C语言的用者编写awkE序带来了极大的方便。作为对q算功能的一U扩展,awkq提供了一pd内置的运函敎ͼ如log、sqr、cos、sin{等Q和一些用于对字符串进行操作(q算Q的函数Q如length、substr{等Q。这些函数的引用大大的提高了awk的运功能?/p>
作ؓ(f)Ҏ(gu)件{UL令的一部分Q关pd断是每种E序设计语言都具备的功能Qawk也不例外?awk中允许进行多U测试,如常用的==Q等于)、!=Q不{于Q?gt;Q大于)?lt;Q小于)?gt;=Q大于等于)?gt;=Q小于等于){等Q同Ӟ作ؓ(f)样式匚wQ还提供了~Q匹配于Q和Q~Q不匚w于)判断?/p>
作ؓ(f)Ҏ(gu)试的一U扩充,awk也支持用逻辑q算W?!(??amp;&Q与Q、||Q或Q和括号Q)q行多重判断Q这大大增强了awk的功能。本文的附录中列Zawk所允许的运、判断以?qing)操作符的优先?/p>
八、awk的流E控?/p>
程控制语句是Q何程序设计语a都不能缺的部分。Q何好的语a都有一些执行流E控制的语句。awk提供的完备的程控制语句cM于C语言Q这l我们编E带来了极大的方ѝ?/p>
1、BEGIN和END:
在awk 中两个特别的表达式,BEGIN和ENDQ这两者都可用于pattern中(参考前面的awk语法Q,提供BEGIN和END的作用是l程序赋予初始状态和在程序结束之后执行一些扫工作。Q何在BEGIN之后列出的操作(在{}内)在awk开始扫描输入之前执行,而END之后列出的操作将在扫描完全部的输入之后执行。因此,通常使用BEGIN来显C变量和预置Q初始化Q变量,使用END来输出最l结果?/p>
例:(x)累计销售文件xs中的销售金额(假设销售金额在记录的第三字D)Q?/p>
$awk
>’BEGIN { FS=”:”;print “l计销售金?#8221;;total=0}
>{print $3;total=total+$3;}
>END {printf “销售金额总计Q?.2f”,total}’ sx
Q注Q?gt;是shell提供的第二提C符Q如要在shellE序awk语句和awk语言中换行,则需在行֊反斜杠)
在这里,BEGIN预置了内部变量FSQ字D分隔符Q和自定义变量total,同时在扫描之前显C出输出行头。而END则在扫描完成后打印出d计?/p>
2、流E控制语?/p>
awk提供了完备的程控制语句Q其用法与C语言cM。下面我们一一加以说明Q?/p>
2.1、if…else语句:
格式Q?br>if(表达?
语句1
else
语句2
格式?#8221;语句1″可以是多个语句,如果你ؓ(f)了方便awk判断也方便你自已阅读Q你最好将多个语句用{}括v来。awk分枝l构允许嵌套Q其格式为:(x)
if(表达?Q?br>{if(表达?Q?br>语句1
else
语句2
}
语句3
else {if(表达?)
语句4
else
语句5
}
语句6
当然实际操作q程中你可能不会(x)用到如此复杂的分枝结构,q里只是Zl出其样式Ş了?/p>
2.2、while语句
格式?
while(表达?
语句
2.3、do-while语句
格式?
do
{
语句
}while(条g判断语句Q?/p>
2.4、for语句
格式为:(x)
for(初始表达?l止条g;步长表达?
{语句}
在awk ?while、do-while和for语句中允怋用break,continue语句来控制流E走向,也允怋用exitq样的语句来退出。break 中断当前正在执行的@环ƈ跛_循环外执行下一条语句。continue从当前位|蟩到@环开始处执行。对于exit的执行有两种情况Q当exit语句不在 END中时QQ何操作中的exit命o(h)表现得如同到了文件尾Q所有模式或操作执行停止,END模式中的操作被执行。而出现在END中的exit导致程序终止?/p>
例:(x)Z
?ji)、awk中的自定义函?/p>
定义和调用用戯q函数是几乎每个高U语a都具有的功能Qawk也不例外Q但原始的awkq不提供函数功能Q只有在nawk或较新的awk版本中才可以增加函数?/p>
函数的用包含两部分Q函数的定义与函数调用。其中函数定义又包括要执行的代码Q函数本w)和从ȝ序代码传递到该函数的临时调用?/p>
awk函数的定义方法如下:(x)
function 函数?参数?{
函数?br>}
在gawk中允许将function省略为funcQ但其它版本的awk不允许。函数名必须是一个合法的标志W,参数表中可以不提供参敎ͼ但在调用函数时函数名后的一Ҏ(gu)号仍然是不可~少的)Q也可以提供一个或多个参数。与C语言怼Qawk的参C是通过值来传递的?/p>
在awk 中调用函数比较简单,其方法与C语言怼Q但awk比C语言更ؓ(f)灉|Q它不执行参数有效性检查。换句话_(d)在你调用函数Ӟ可以列出比函数预计(函数定义中规定)的多或少的参敎ͼ多余的参C(x)被awk所忽略Q而不的参数Qawk它们置为缺省?或空字符Ԍ具体|ؓ(f)何|取决于参数的用方式?/p>
awk函数有两U返回方式:(x)隐式q回和显式返回。当awk执行到函数的l尾Ӟ它自动地q回到调用程序,q是函数是隐式返回的。如果需要在l束之前退出函敎ͼ可以明确C用返回语句提前退出。方法是在函C使用形如Qreturn q回?格式的语句?/p>
例:(x)下面的例子演CZ函数的用。在q个CZ中,定义了一个名为print_header的函敎ͼ该函数调用了两个参数FileName和PageNumQ?FileName参数传给函数当前使用的文件名QPageNum参数是当前页的页受这个函数的功能是打华ͼ昄Q出当前文g的文件名Q和当前늚号。完成这个功能后Q这个函数将q回下一늚号?/p>
nawk
>’BEGIN{pageno=1;file=FILENAME
>pageno=print_header(fileQpageno)Q?调用函数print_header
>printf(”当前页hQ?dn”,pageno);
>}
>#定义函数print_header
>function print_header(FileName,PageNum){
>printf(”%s %dn”,FileName,PageNum); >PageNum++;return PageNUm;
>}
>}’ myfile
执行q个E序显C如下内容:(x)
myfile 1
当前页hQ?
十、awk高输入输出
1.d下一条记录:(x)
awk的next语句Dawkd下一个记录ƈ完成模式匚wQ然后立x行相应的操作。通常它用匚w的模式执行操作中的代码。nextDq个记录的Q何额外匹配模式被忽略?/p>
2.单地d一条记?/p>
awk ?getline语句用于单地d一条记录。如果用h一个数据记录类g个物理记录,那么getline尤其有用。它完成一般字D늚分离(讄字段变量$0 FNR NF NR)。如果成功则q回1Q失败则q回0Q到达文件尾Q。如果需单地d一个文Ӟ则可以编写以下代码:(x)
例:(x)CZgetline的?/p>
{while(getline==1)
{
#process the inputted fields
}
}
也可以getline保存输入数据在一个字D中Q而不是通过使用getline variable的Ş式处理一般字Dc(din)当使用q种方式ӞNF被置?QFNR和NR被增倹{?/p>
用户也可以用getline<"filename"方式从一个给定的文g中输入数据,而不是从命o(h)行所列内容输入数据。此Ӟgetline完成一般字D分(讄字段变量$0和NF)。如果文件不存在Q返?1,成功Q返?,q回0表示p|。用户可以从l定文g中读取数据到一个变量中Q也可以用stdin(标准输入讑֤Q或一个包含这个文件名的变量代替filename。值得注意的是当用这U方式时不修改FNR和NR?/p>
另一U用getline语句的方法是从UNIX命o(h)接受输入Q例如下面的例子:
例:(x)CZ从UNIX命o(h)接受输入
{while("who -u"|getline)
{
#process each line from the who command
}
}
当然Q也可以使用如下形式:
"command" | getline variable
3.关闭文g:
awk中允许在E序中关闭一个输入或输出文gQ方法是使用awk的close语句?/p>
close("filename"t
filename可以是getline打开的文Ӟ也可以是stdin,包含文g名的变量或者getline使用的确切命令)。或一个输出文Ӟ可以是stdoutQ包含文件名的变量或使用道的确切命令)?/p>
4.输出C个文?
awk中允许用如下方式结果输出到一个文Ӟ(x)
printf("hello word!n"t>“datafile”
?br>printf(”hello word!n”t>>”datafile”
5.输出C个命?/p>
awk中允许用如下方式结果输出到一个命令:(x)
printf(”hello word!n”t|”sort-t’,'”
十一、awk与shell script混合~程
因ؓ(f)awk可以作ؓ(f)一个shell命o(h)使用Q因此awk能与shell批处理程序很好的融合在一Pq给实现awk与shellE序的合编E提供了可能。实现合编E的关键是awk与shell script之间的对话,换言之,是awk与shell script之间的信息交?awk从shell script中获取所需的信息(通常是变量的|、在awk中执行shell命o(h)行、shell script命令执行的l果送给awk处理以及(qing)shell scriptdawk的执行结果等{?/p>
1.awkdShell scriptE序变量
在awk中我们可以通过“’$变量?#8217;”的方式读取sell scrpitE序中的变量?/p>
例:(x)在下面的CZ中,我们读取sell scrpitE序中的变量NameQ该变量存放的是文本myfile的撰写者,awk打印出q个人名?/p>
$cat writename
:
# @(#)
#
.
.
.
Name=”张三” nawk ‘BEGIN {name=”‘Name’”; printf(”t%st撰写?sn”,FILENAME,name”t;}
{…}END{…}’ myfile
.
.
.
2.shell命o(h)的执行结果送给awk处理
作ؓ(f)信息传送的一U方法,我们可以一条shell命o(h)的结果通过道U(|Q传递给awk处理Q?/p>
例:(x)CZawk处理shell命o(h)的执行结?/p>
$who -u | awk ‘{printf(”%s正在执行%sn”,$2,$1)}’
该命令将打印出注册终端正在执行的E序名?/p>
3.shell scriptE序读awk的执行结?/p>
Z实现shell scriptE序dawk执行的结果,我们可以采取一些特D的Ҏ(gu)Q例如我们可以用变量?`awk语句`的Ş式将awk执行的结果存攑օ一?shell script变量。当然也可以用管道线的方法将awk执行l果传递给shell scriptE序处理?/p>
例:(x)作ؓ(f)传送消息的机制之一QUNIX提供了一个向其所有用户传送消息的命o(h)wallQ意思是write to all写给所有用PQ该命o(h)允许向所有工作中的用Pl端Q发送消息。ؓ(f)此,我们可以通过一Dshell批处理程序wall.shell来模拟这一E序Q事实上比较老的版本中wall是一Dshell批处理程序:(x)
$cat wall.shell
:
# @(#) wall.shell:发送消息给每个已注册终?br>#
cat >/tmp/$$
#用户录入消息文本 who -u | awk ‘{print $2}’ | while read tty
do
cat /tmp/$$>$tty
done
在这个程序里Qawk接受who -u命o(h)的执行结果,该命令打印出所有已注册l端的信息,其中W二个字D|已注册终端的讑֤名,因此用awk命o(h)析出该设备名Q然后用while read tty语句循环dq些文g名到变量Qshell script变量Qtty中,作ؓ(f)信息传送的l结地址?/p>
4.在awk中执行shell命o(h)行?嵌入函数system()
system()是一个不适合字符或数字类型的嵌入函数Q该函数的功能是处理作ؓ(f)参数传递给它的字符丌Ӏsystem对这个参数的处理是其作ؓ(f)命o(h)处理Q也是说将其当作命令行一样加以执行。这使得用户在自qawkE序需要时可以灉|地执行命令或脚本?/p>
例:(x)下面的程序将使用system嵌入函数打印用户~制好的报表文gQ这个文件存攑֜名ؓ(f)myreport.txt的文件中。ؓ(f)Uv见,我们只列Z其END部分Q?/p>
.
.
.
END {close(”myreport.txt”t;system(”lp myreport.txt”t;}
在这个示例中Q我们首先用close语句关闭了文件myreport.txt文gQ然后用system嵌入函数myreport.txt送入打印机打印?/p>
写到q里Q我不得不跟朋友们说再见了,实在地说Q这些内容仍然是awk的初步知识,?sh)脑永远是前q的U学Qawk也不例外Q本所能做的只是在你前行的漫O镉K中铺^一D小开端,剩下的\q得靠你自己去走。老实_(d)如果本文真能l你前行的\上带来些许的方便Q那本hq了Q?/p>
如对本篇有Q何疑问,请E-mail To:Chizlong@yeah.net或到主页http://chizling.yeah.net中留a?br>附录Q?/p>
1.awk的常规表辑ּ元字W?/p>
换码序列
^ 在字W串的开头开始匹?br>$ 在字W串的结ּ始匹?br>. 与Q何单个字W串匚w
[ABC] 与[]内的M字符匚w
[A-Ca-c] 与A-C?qing)a-c范围内的字符匚wQ按字母表顺序)
[^ABC] 与除[]内的所有字W以外的M字符匚w
Desk|Chair 与Desk和Chair中的M个匹?br>[ABC][DEF] 兌。与A、B、C中的M字符匚wQ且其后要跟D、E、F中的M个字W?br>* 与A、B或C中Q一个出?ơ或多次的字W相匚w
+ 与A、B或C中Q何一个出?ơ或多次的字W相匚w
Q?与一个空串或A、B或C在Q何一个字W相匚w
QBlue|BlackQberry 合ƈ常规表达式,与Blueberry或Blackberry相匹?/p>
2.awk术q算W?/p>
q算W?用?br>—————?br>x^y x的yơ幂
x**y 同上
x%y 计算x/y的余敎ͼ求模Q?br>x+y x加y
x-y x减y
x*y x乘y
x/y x除y
-y 负y(y的开关符?;也称一目减
++y y?后用y(前置加)
y++ 使用y值后?Q后~加)
–y y?后用y(前置减)
y– 使用后y?(后缀减)
x=y y的Dlx
x+=y x+y的Dlx
x-=y x-y的Dlx
x*=y x*y的Dlx
x/=y x/y的Dlx x%=y x%y的Dlx
x^=y x^y的Dlx
x**=y x**y的Dlx
3.awk允许的测试:(x)
操作W?含义
x==y x{于y
x!=y x不等于y
x>y x大于y
x>=y x大于或等于y
xx<=y x于或等于y?
x~re x匚w正则表达式re?
x!~re x不匹配正则表辑ּre?
4.awk的操作符(按优先升序排列)
= ?=?-=?*= ?= ?%=
||
&&
> >= < <= == != ~ !~
xy (字符串连l,’x'’y'变成”xy”Q?br>+ -
* / %
++ –
5.awk内置变量Q预定义变量Q?/p>
说明Q表中v表C第一个支持变量的工具Q下同)QA=awkQN=nawk,P=POSIX awk,G=gawk
V 变量 含义 ~省?br>—————————————————?#8211;
N ARGC 命o(h)行参C?br>G ARGIND 当前被处理文件的ARGV标志W?br>N ARGV 命o(h)行参数数l?br>G CONVFMT 数字转换格式 %.6g
P ENVIRON UNIX环境变量
N ERRNO UNIXpȝ错误消息
G FIELDWIDTHS 输入字段宽度的空白分隔字W串
A FILENAME 当前输入文g的名?br>P FNR 当前记录?br>A FS 输入字段分隔W?I格
G IGNORECASE 控制大小写敏?Q大写敏感Q?br>A NF 当前记录中的字段个数
A NR 已经d的记录数
A OFMT 数字的输出格?%.6g
A OFS 输出字段分隔W?I格
A ORS 输出的记录分隔符 新行
A RS 输入的记录他隔符 新行
N RSTART 被匹配函数匹配的字符串首
N RLENGTH 被匹配函数匹配的字符串长?br>N SUBSEP 下标分隔W?“34″
6.awk的内|函?/p>
V 函数 用途或q回?br>———————————————?br>N gsub(reg,string,target) 每次常规表达式reg匚w时替换target中的string
N index(search,string) q回string中search串的位置
A length(string) 求串string中的字符个数
N match(string,reg) q回常规表达式reg匚w的string中的位置
N printf(format,variable) 格式化输出,按format提供的格式输出变量variable?br>N split(string,store,delim) Ҏ(gu)分界Wdelim,分解string为store的数l元?br>N sprintf(format,variable) q回一个包含基于format的格式化数据Qvariables是要攑ֈ串中的数?br>G strftime(format,timestamp) q回一个基于format的日期或者时间串Qtimestmp是systime()函数q回的时?br>N sub(reg,string,target) W一ơ当常规表达式reg匚wQ替换target串中的字W串
A substr(string,position,len) q回一个以position开始len个字W的子串
P totower(string) q回string中对应的写字符
P toupper(string) q回string中对应的大写字符
A atan(x,y) x的余?弧度)
N cos(x) x的余?弧度)
A exp(x) e的xq?br>A int(x) x的整数部?br>A log(x) x的自然对数?br>N rand() 0-1之间的随机数
N sin(x) x的正?弧度)
A sqrt(x) x的^Ҏ(gu)
A srand(x) 初始化随机数发生器。如果忽略xQ则使用system()
G system() q回?970q??日以来经q的旉Q按U计)
q组命o(h)在搜索与定位文g中特定的主题斚w非常有用。要搜烦的模式可以被认ؓ(f)是一些关键词Q?zhn)可以用它们来搜烦文g中包含的q些关键词。编写程序时Q可以用它来L某一个函敎ͼ或是相关的词l。grep 命o(h)的搜索功能比 fgrep 强大Q因?grep 命o(h)的搜索模式可以是正则表达式,?fgrep 却不能?/p>
该组命o(h)中的每一个命令都有一l选项Q利用这些选项可以改变其输出方式。例如,可以在搜索到的文本行上加入行P或者只输出文本行的行号Q或者输出所有与搜烦模式不匹配的文本行,或只单地输出已搜索到指定模式的文件名Qƈ且可以指定在查找模式时忽略大写?/p>
q组命o(h)在指定氖淙胛募胁檎矣肽Q狡ヅ涞男小QQ挥兄付ㄎ募?yng)虼颖曜际?中读取。正常情况下Q每个匹配的行被昄到标准输出。如果要查找的文件是多个Q则在每一行输Z前加上文件名?/p>
语法Q? grep [选项] [查找模式] [文g?Q文件名2Q?#8230;…] egrep [选项] [查找模式] [文g?Q文件名2Q?#8230;…] fgrep [选项] [查找模式] [文g?Q文件名2Q?#8230;…]
该命令的各选项含义如下Q?/strong>
-E 每个模式作ؓ(f)一个扩展的正则表达式对待?-F 每个模式作ؓ(f)一l固定字W串对待Q以新行分隔Q,而不作ؓ(f)正则表达式?-b 在输出的每一行前昄包含匚w字符串的行在文g中的字节偏移量?-c 只显C匹配行的数量?-i 比较时不区分大小写?-h 在查扑֤个文件时Q指Cgrep不要文件名加入到输Z前?-l 昄首次匚w串所在的文g名ƈ用换行符其隔开? 当在某文件中多次出现匚w串时Q不重复昄此文件名?-n 在输出前加上匚w串所在行的行P文g首行行号?Q?-v 只显CZ包含匚w串的行?-x 只显C整行严格匹配的行?-e expression 指定(g)索用的模式。用于防止以“-”开头的模式被解释ؓ(f)命o(h)选项?-f expfile 从expfile文g中获取要搜烦的模式,一个模式占一行?/pre>对该l命令的使用q需注意以下斚wQ?/p>
在命令后键入搜烦的模式,再键入要搜烦的文件。其中,文g名列表中也可以用特D字W,?“*” {,用来生成文g名列表。如果想在搜索的模式中包含有I格的字W串Q可以用单引h要搜索的模式括v来,用来表明搜烦的模式是由包含空格的字符串组成。否则,Shell 把I格认ؓ(f)是命令行参数的定界符Q?grep 命o(h)把搜烦模式中的单词解释为文件名列表中的一部分。在下面的例子中Qgrep 命o(h)在文?example 中搜索模?“text file”?/p>
grep ’text file’ example用户可以在命令行上用ShellҎ(gu)字符来生成将要搜索的文g名列表。在下面的例子中Q特D字W?#8220;*”用来生成一个文件名列表Q该列表包含当前目录下所有的文g。该命o(h)搜索出当前目录下所有文件中与模式匹配的行?/p>
grep data *Ҏ(gu)字符在搜索一l指定的文g旉常有用。例如,如果x索所有的CE序源文件中特定的模式,(zhn)可以用“*.c”来指定文件名列表。假讄L(fng) CE序中包含一些不必要的{向语句(goto语句Q,惌扑ֈq些语句Q可以用如下的命令来搜烦q显C所有包?goto语句的代码行Q?/p>
grep goto *.c用户可以在命令行上键入搜索模式,也可以?-f 选项从指定文件中d要搜索的模式。在文g中,每个搜烦模式占一行。如果经常要搜烦一l常见字W串Ӟq个功能非常有用。在下面的例子中Q用戯在文?exam 中搜索字W串 “editor” ?“create”Q就把要搜烦的模式放|在文g mypats 中,然后Qgrep 命o(h)从文?mypats 中读取要搜烦的模式?/p>
grep -f mypats exam
]]>
GAWK
W一?前言
W二??br>W三?d输入档案
W四?印出
W五?Patterns
W六?式(Expression)作ؓ(f)Actions的叙q?br>W七?Actions里面的控制叙q?br>W八?内徏函式(Built-in Functions)
W九(ji)?使用者定义的函式
W十?□例
W十一?l论
Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q?/p>
W一?前言
awk 是一个程式语aQ对D料的处理h很强的功能。对於文
字档里的资料做修攏V比寏V抽取等的处理,awk 能够以很短的E式
L地完成。如果?C ?Pascal {语a写程式完成上q的动作Q?br>?x)不方便且很p旉Q所写的E式也会(x)很大?/p>
awk 能够依照使用者的定义格式来分解输入资料,也可依照使用
者定义的格式来印料?/p>
awk 名称的由来是由它的原始设计者的姓氏之第一个字母而命?br>QAlfred V. Aho, Peter J. Weinberger, Brian W. Kernighan?br>awk最初在1977q完成。一个新版本的awk?985q被发表Q它的功?br>比旧版本增强不少?/p>
gawk 是GNU所做的 awkQgawk 最初在1986q完成,之後不断?br>被改q、更新。gawk 包含 awk 的所有功能?/p>
往後的 gawk 以下面?个输入档案来做例子说明?/p>
档案’BBS-list’Q?br>aardvark 555-5553 1200/300 B
alpo-net 555-3412 2400/1200/300 A
barfly 555-7685 1200/300 A
bites 555-1675 2400/1200/300 A
camelot 555-0542 300 C
core 555-2912 1200/300 C
fooey 555-1234 2400/1200/300 B
foot 555-6699 1200/300 B
macfoo 555-6480 1200/300 A
sdace 555-3430 2400/1200/300 A
sabafoo 555-2127 1200/300 C
档案’shipped’Q?br>Jan 13 25 15 115
Feb 15 32 24 226
Mar 15 24 34 228
Apr 31 52 63 420
May 16 34 29 208
Jun 31 42 75 492
Jul 24 34 67 436
Aug 15 34 47 316
Sep 13 55 37 277
Oct 29 54 68 525
Nov 20 87 82 577
Dec 17 35 61 401
Jan 21 36 64 620
Feb 26 58 80 652
Mar 24 75 70 495
Apr 21 70 74 514
W二??/p>
gawk 的主要功能是针对档案的每一?line)搜寻指定?patterns
。当一行里有符合指定的 patternsQgawk ׃(x)在此一行执行被指定
?actions?gawk 依此方式处理输入档案的每一行直到输入档案结
束?/p>
gawk E式是由很多?pattern ?action 所l成Qaction 写在
大括?{ } 里面Q一个pattern後面p著一个action。整?gawk E?br>式会(x)像下面的样子Q?/p>
pattern {action}
pattern {action}
?gawk E式里面的规则,pattern ?action 能够被省略,?br>是两个不能同时被省略。如?pattern 被省略,Ҏ(gu)输入档里面的
每一行,action 都会(x)被执行。如?action 被省略,内定?action
则会(x)印出所有符?pattern 的输入行?br>2.1 如何执行gawkE式
基本上,?个方法可以执行gawkE式?/p>
□如?gawk E式很短Q则 gawk 可以直接写在 command lineQ如下所C:(x)
gawk ‘program’ input-file1 input-file2 …
其中 program 包括一?pattern ?action?/p>
□如?gawk E式较长Q较为方便的做法是将 gawk E式存在一个档案,
?patterns ?actions 写在档名?program-file 的档案里面,执行
gawk 的格式如下所C:(x)
gawk -f program-file input-file1 input-file2 …
gawk E式的档案不止一个时Q执行gawk 的格式如下所C:(x)
gawk -f program-file1 -f program-file2 … input-file1
input-file2 …
2.2 一个简单的例子
现在我们举一个简单的例子Q因?gawk E式很短Q所以将 gawk E?br>式直接写?command line?/p>
gawk ‘/foo/ {print $0}’ BBS-list
实际?gawk E式?/foo/ {print $0}?foo/ ?patternQ意思ؓ(f)?br>寻输入档里的每一行是否含有子字串 ‘foo’Q如果含?‘foo’ 则执?action?br>action ?print $0Q是现在这一行的内容印出。BBS-list 是输入的档案?/p>
执行完上q指令後Q会(x)印出下面的结果:(x)
fooey 555-1234 2400/1200/300 B
foot 555-6699 1200/300 B
macfoo 555-6480 1200/300 A
sabafoo 555-2127 1200/300 C
2.3 一个较复杂的例?/p>
gawk ‘$1 == “Feb” {sum=$2+$3} END {print sum}’ shipped
现在q个例子?x)将输入?’shipped’ 的第一个栏位与 “Feb” 做比?br>Q如果相{,则其对应的第2栏位与第3栏位的g(x)被加到变?sum?br>Ҏ(gu)输入档的每一行重复上q的动作Q直到输入档的每一行都被处?br>qؓ(f)止。最後将 sum 的值印出。END {print sum} 的意思ؓ(f)在所有的?br>入读完之後,执行一?print sum 的动作,也就是把 sum 的值印出?/p>
下面是执行的l果Q?br>84
W三?d输入档案
gawk的输入可以从标准输入或指定的档案里读取。输入的d?br>位被UCؓ(f)”记录”(records)Qgawk 在做处理Ӟ是一个记录一个记
录地处理。每个记录的内定值是一?line)Q一个记录又被分为多?br>栏位(fields)?br>3.1 如何输入分解成记录(records)
gawk 语言?x)把输入分解成记?record)。记录与记录之间是以
record separator 隔开Qrecord separator 的内定值是表示C行的
字元(newline character)Q因此内定的 record separator 使得文字
的每一行是一个记录?/p>
record separator 随著内徏变数 RS 的改变而改变。RS 是一个字Ԍ
它的内定值是”\n”。仅?RS 的第一个字元是有效的,它被当作 record
separatorQ?RS 的其它字元会(x)被忽略?/p>
内徏变数 FNR ?x)储存目前的输入档案已经被读取的记录之个数。内
建变?NR ?x)储存目前?f)止所有的输入档案已经被读取的记录之个数?br>3.2 栏位(field)
gawk ?x)自动将每个记录分解成多个栏?(field)。类似於字在一
行里面,gawk 的内定动作会(x)认ؓ(f)栏位之间是以 whitespace 分开。在
gawk 里,whitespace 的意思是一个或多个I白?tabs?/p>
?gawk E式里面Q以’$1′表示W一个栏位,’$2′表示W二个栏?br>Q依此类推。D个例子,假设输入的一行如下所C:(x)
This seems like a pretty nice example.
W一个栏位或 $1 ?#8217;This’Q第二个栏位?$2 ?’seems’Q依此类推?br>有个地方值得特别注意Q第七个栏位?$7 ?#8217;example.’而非’example’?/p>
不论有多栏位,$NF 可用来表CZ个记录的最後一个栏位。以
上面的例子ؓ(f)例,$NF ?$7 相同Q也是’example.’?/p>
NF 是一个内建变敎ͼ它的DC目前这个记录之栏位的个数?/p>
$0Q看h好像是第零个栏位Q它是一个特例,它表C整个记录?/p>
下面是一个较复杂的例子:(x)
gawk ‘$1~/foo/ {print $0}’ BBS-list
l果如下Q?br>fooey 555-1234 2400/1200/300 B
foot 555-6699 1200/300 B
macfoo 555-6480 1200/300 A
sabafoo 555-2127 1200/300 C
q个例子是把输入?#8217;BBS-list’的每个记录的W一个栏位作(g)查,?br>果它含有子字?#8217;foo’Q则q一个记录会(x)被印出?br>3.3 如何记录分解成栏位
gawk Ҏ(gu) field separator 一个记录分解成栏位。field sepa-
rator 以内建变?FS 表示?/p>
举个例子Q假?field separator ?#8217;oo’Q则下面的行Q?/p>
moo goo gai pan
?x)被分成三个栏位Q?#8217;m'?#8217; g’?#8217; gai pan’?/p>
?gawk E式里,可以使用’='来改?FS 的倹{例?
gawk ‘BEGIN {FS=”,”}; {print $2}’
输入行如下:(x)
John Q. Smith, 29 Oak St., Walamazoo, MI 42139
执行gawk的结果将印出字串 ‘ 29 Oak St.’。BEGIN 後面?action ?x)?br>W一个记录被d之前执行一ơ?br>W四?印出
在gawkE式里,actions 最常做的事是印出(printing)。简?br>的印出,使用 printe叙述。复杂格式的印出Q?printf 叙述?br>4.1 print叙述
print 叙述用在单、标准的输出格式。叙q的格式如下所C:(x)
print item1, item2, …
输出Ӟ各个 item 之间?x)以一个空白分开Q最後会(x)换行(newline)?/p>
如果 ‘print’叙述之後没有跟著M东西Q它?#8217;print $0′的效
果一P它会(x)印出现在的记?record)。要印出I白行可使用’print
“”‘?印出一D固定的文字Q可用双引号文字的两边括v来,例如
‘print “Hello there”‘?/p>
q里是一个例子,它会(x)把每个输入记录的前二个栏位印出:(x)
gawk ‘{print $1,$2}’ shipped
l果如下所C:(x)
Jan 13
Feb 15
Mar 15
Apr 31
May 16
Jun 31
Jul 24
Aug 15
Sep 13
Oct 29
Nov 20
Dec 17
Jan 21
Feb 26
Mar 24
Apr 21
4.2 Output Separators
前面我们已提q如?print 叙述包含有多?itemQitem 之间
用逗点分开Q则印出时各个item?x)被一个空白隔开。你能够使用M
的字串作?output field separatorQ可以经由内建变?OFS 的设
定来更改 output field separator。OFS 的初始gؓ(f)” “Q即一格的
I白?/p>
整个 print 叙述的输UCؓ(f) output record。print 叙述?br>?output record 之後Q会(x)接著输出一个字Ԍ此字串称?output
record separator。内建变?ORS 用来指明此字丌ӀORS 的初始?br>?“\n”Q也是换行?/p>
下面q个例子?x)印出每个记录的W一个栏位和W二个栏位,此二
个栏位之间以分号’;'分开Q每行输Z後会(x)加入一个空白行?/p>
gawk ‘BEGIN {OFS=”;”; ORS=”\n\n”} {print $1, $2}’ BBS-list
l果如下所C:(x)
aardvark;555-5553
alpo-net;555-3412
barfly;555-7685
bites;555-1675
camelot;555-0542
core;555-2912
fooey;555-1234
foot;555-6699
macfoo;555-6480
sdace;555-3430
sabafoo;555-2127
4.3 printf叙述
printf 叙述?x)得输出格式较?gu)_地控制。printf 叙述可以
指定每个 item 印出的宽度,也可以指定数字的各种型式?/p>
printf 叙述的格式如下:(x)
printf format, item1, item2, …
print ?printf 的差别是在於 format, printf 的引数比 print
多了字串 format。format 的型式与 ANSI C ?printf 之格式相同?/p>
printf q不?x)做自动换行的动作。内建变?OFS ?ORS ?printf ?br>q没有Q何媄响?/p>
格式的指定以字元’%'开始,後面接著格式控制字母?/p>
格式控制字母如下所C:(x)
‘c’ 数字以 ASCII 字元印出?br>例如’printf “%C”,65′?x)印出字?#8217;A'?/p>
‘d’ 印出十进位的整数?/p>
‘i’ 印出十进位的整数?/p>
‘e’ 数字以U学W号的Ş式印出?br>例如
print “$4.3e”,1950
l果?x)印?#8217;1.950e+03′?/p>
‘f’ 数字以点的Ş式印出?/p>
‘g’ 数字以U学W号的Ş式或点的Ş式印出。数字的l对值如?br>大於{於0.0001则以点的Ş式印出,否则以科学符L(fng)形式?br>出?/p>
‘o’ 印出无号的八q位整数?/p>
’s’ 印出一个字丌Ӏ?/p>
‘x’ 印出无号的十六进位整数?0?5?#8217;a'?#8217;f'表示?/p>
‘X’ 印出无号的十六进位整数?0?5?#8217;A'?#8217;F”表示?/p>
‘%’ 它ƈ不是真正的格式控制字母,’%%”印?#8221;%’?/p>
?% 与格式控制字母之间可加入 modifierQmodifier 是用来进一
步控制输出的格式。可能的 modifier 如下所C:(x)
‘-’ 使用?width 之前Q指明是向左靠齐。如?#8217;-'没有出现Q则?x)?br>被指定的宽度向右靠齐。例如:(x)
printf “%-4S”, “foo”
?x)印?#8217;foo ‘?/p>
‘width’ q一个数字指C相对应的栏位印出时的宽度。例如:(x)
printf “%4s”,”foo”
?x)印?#8217; foo’?/p>
width 的值是一个最宽度而非最大宽度。如果一?item ?br>值需要的宽度?width 大,则不?width 的媄响。例?/p>
printf “%4s”,”foobar”
印?#8217;foobar’?/p>
‘.prec’ 此数字指定印出时的精度。它指定数点右边的位数。如
果是要印Z个字Ԍ它指定此字串最多会(x)被印出多个?br>元?br>W五?patterns
?gawk E式里面Q当 pattern W合现在的输入记?record)Q其
相对应的 action 才会(x)被执行?br>5.1 Pattern的种c?/p>
q里?gawk 的各U?pattern 型式作一整理Q?/p>
/regular expression/
一?regular expression 当作一?pattern。每当输入记?(
record)含有 regular expression p为符合?/p>
expression
一个单一?expression。当一个g?0 或一个字串不是空的,
则可视ؓ(f)W合?/p>
pat1,pat2
一对的 patterns 以逗号分开Q指定记录的□围?/p>
BEGIN
END
q是特别?pattern, gawk 在开始执行或要结束时?x)分别执行?br>对应於BEGIN或END?action?/p>
null
q是一个空的patternQ对於每个输入记录皆视ؓ(f)W合pattern?br>5.2 Regular Expressions当作Patterns
一?regular expression 可简写ؓ(f) regexpQ是一U描q字串的?br>法。一?regular expression 以斜U?’/')包围当作 gawk ?pattern?/p>
如果输入记录含有 regexp p为符合。例如:(x)pattern ?/foo/Q?br>Ҏ(gu)M输入记录含有’foo’则视为符合?/p>
下面的例子会(x)含?#8217;foo’的输入记录之W?个栏位印出?/p>
gawk ‘/foo/ {print $2}’ BBS-list
l果如下Q?br>555-1234
555-6699
555-6480
555-2127
regexp 也能使用在比较的式?/p>
exp ~ /regexp/
如果 exp W合 regexpQ则l果为真(true)?/p>
exp !~ /regexp/
如果 exp 不符?regexpQ则l果为真?br>5.3 比较的算式当作Patterns
比较?pattern 用来试两个数字或字串的关系诸如大於、等?br>、小方{下面列Z些比较的patternQ?/p>
x
上面所提到?x ?yQ如果二者皆是数字则视ؓ(f)数字之间的比较,
否则它们?x)被转换成字串且以字串的形式做比较。两个字串的比较Q?br>?x)先比较W一个字元,然後比较W二个字元,依此cLQ直到有不同
的地方出Cؓ(f)止。如果两个字串在较短的一个结束之前是相等Q则?br>为长的字串比短的字串大。例?“10″ ?“9″ ,”abc” ?“abcd” ?br>5.4 使用布林q算的Patterns
一个布?boolean) pattern 是用布林运?#8221;?#8221;(’||’)Q?#8221;?#8221;
(’&&’)Q?#8221;?#8221;(’!')来组合其它的pattern?br>例如Q?/p>
gawk ‘/2400/ && /foo/’ BBS-list
gawk ‘/2400/ || /foo/’ BBS-list
gawk ‘! /foo/’ BBS-list
W六?式(Expression)作ؓ(f)Actions的叙q?/p>
式(Expression) 是gawkE式里面action的基本构成者?br>6.1 术q算
gawk 里的术q算如下所C:(x)
x+y ?br>x-y ?br>-x ?br>+x 正。实际上没有M影响?br>x*y ?br>x/y ?br>x%y 求馀数。例?5%3=2?br>x^y
x**y x ?y ơ方。例?^3=8?br>6.2 比较式与布林算?/p>
比较式 (comparison expression) 用来比较字串或数字的关系
Q运符号与 C 语言相同。表列如下:(x)
x
x>y
x>=y
x==y
x!=y
x~y
x!~y
比较的结果ؓ(f)?true)则其值是 1。否则其值是 0?/p>
布林式(boolean expression)有下面三U:(x)
boolean1 && boolean2
boolean1 || boolean2
! boolean
6.3 条g式(Conditional Expressions)
一个条件式式是一U特别的式Q它含有3个运元?br>条g式算式与C语言的相同:(x)
selector ? if-true-exp : if-false-exp
它有3个子式。第一个子式selector 首先?x)被计算。如果是?
则if-true-exp?x)被计算且它的值变成整个算式的倹{否则if-false-
exp ?x)被计算且它的值变成整个算式的倹{?/p>
例如下面的例子会(x)产生x的绝对|(x)
x>0 ? x : -x
W七?Actions里面的控制叙q?/p>
?gawk E式里面Q控制叙q诸?if、while {控制程式执行的?br>E。在 gawk 里的控制叙述?C 的类伹{?/p>
很多的控制叙qC(x)包括其它的叙qͼ被包括的叙述UCؓ(f) body。假
?body 里面包括一个以上的叙述Q必M大括?{ } 这些叙q括?br>来,而各个叙qC间需以换?newline)或分号隔开?br>7.1 if 叙述
if (condition) then-body [else else-body]
如果 condition 为真(true)Q则执行 then-bodyQ否则执?else-body?/p>
举一个例子如下:(x)
if (x % 2 == 0)
print “x is even”
else
print “x is odd”
7.2 while 叙述
while (condition)
body
while 叙述做的W一件事是试 condition。假?condition 为真?br>执行 body 的叙q。body 的叙q执行完後,?x)再?conditionQ假?br>condition 为真Q则 body ?x)再度被执行。这个过E会(x)一直被重复直到
condition 不再是真。如?condition W一ơ测试就是伪(false)Q则
body 从没有被执行?/p>
下面的例子会(x)印出每个输入记录(record)的前三个栏位?/p>
gawk ‘{ i=1
while (i <= 3) {
print $i
i++
}
}'
7.3 do-while 叙述
do
body
while (condition)
q个 do loop 执行 body 一ơ,然後只要 condition 是真则会(x)重复执行 body?br>即开始时 condition 是伪Qbody 也会(x)被执行一ơ?/p>
下面的例子会(x)印出每个输入记录十次?/p>
gawk '{ i= 1
do {
print $0
i++
} while (i <= 10)
}'
7.4 for 叙述
for (initialization; condition; increment)
body
此叙q开始时?x)执行initializationQ然後只?condition是真Q它
?x)重复执行body与做increment ?/p>
下面的例子会(x)印出每个输入记录的前三个栏位?/p>
gawk '{ for (i=1; i<=3; i++)
print $i
}'
7.5 break 叙述
break 叙述?x)蟩出包含它?for、while、do-while 回圈的最内层?/p>
下面的例子会(x)扑ևM整数的最除敎ͼ它也?x)判断是否?f)质数?/p>
gawk '# find smallest divisor of num
{ num=$1
for (div=2; div*div <=num; div++)
if (num % div == 0)
break
if (num % div == 0)
printf "Smallest divisor of %d is %d\n", num, div
else
printf "%d is prime\n", num }'
7.6 continue 叙述
continue 叙述使用?for、while、do-while 回圈内部Q它?x)?br>q回?body 的剩馀部分Q得它立刻q行下一ơ回圈的执行?/p>
下面的例子会(x)印出 0 ?20 的全部数字,但是 5 q不?x)被印出?/p>
gawk 'BEGIN {
for (x=0; x<=20; x++) {
if (x==5)
continue
printf ("%d",x)
}
print ""
}'
7.7 next 叙述、next file 叙述、exit 叙述
next 叙述 gawk 立刻停止处理目前的记?record)而l下一
个记录?/p>
next file 叙述cM next。然而,它强q?gawk 立刻停止处理目前
的资料档?/p>
exit 叙述?x)?gawk E式停止执行而蟩出。然而,如果 END 出现
Q它?x)去执?END ?actions?br>W八?内徏函式(Built-in Functions)
内徏函式?gawk 内徏的函式,可在 gawk E式的Q何地方呼叫内?br>函式?br>8.1 数值方面的内徏函式
int(x) 求出 x 的整数部份,朝向 0 的方向做舍去。例如:(x)int(3.9)
?3Qint(-3.9) ?-3?br>sqrt(x) 求出 x 正的qx根倹{例 sqrt(4)=2
exp(x) 求出 x 的次斏V例 exp(2) x?e*e ?br>log(x) 求出 x 的自然对数?br>sin(x) 求出 x ?sine |x 是弪度量?br>cos(x) 求出 x ?cosine |x 是弪度量?br>atan2(y,x) ?y/x ?arctangent |所求出的值其单位是弪度量?br>rand() 得出一个ؕ数倹{此乱数值^均分布在 0 ?1 之间。这?br>g?x)?0Q也不会(x)?1?br>每次执行 gawkQrand 开始生数字从相同Ҏ(gu) seed?br>srand(x) 讑֮产生乱数的开始点?seed ?x。如果在W二ơ你?br>定相同的 seed |你将再度得到相同序列的ؕ数倹{?br>如果省略引数 xQ例?srand()Q则现在的日期、时间会(x)
被当?seed。这个方法可使得乱数值是真正不可预测的?br>srand 的传回?return value)是前ơ所讑֮?seed 倹{?br>8.2 字串斚w的内建函?/p>
index(in, find)
它会(x)在字?in 里面Q寻扑֭?find W一ơ出现的地方Q传回值是
字串 find 出现在字?in 里面的位|。如果在字串 in 里面找不到字
?findQ则传回gؓ(f) 0?br>例如Q?br>print index("peanut","an")
?x)印?3?/p>
length(string)
求出 string 有几个字元?br>例如Q?br>length("abcde")
?5?/p>
match(string,regexp)
match 函式?x)在字?string 里面Q寻扄?regexp 的最ѝ最?br>左边的子字串。传回值是 regexp ?string 的开始位|,?index
倹{?br>match 函式?x)设定内在变?RSTART {於 indexQ它也会(x)讑֮内在?br>?RLENGTH {於W合的字元个数。如果不W合Q则?x)设?RSTART ?br>0、RLENGTH ?-1?/p>
sprintf(format,expression1,...)
?printf cMQ但?sprintf q不印出Q而是传回字串?br>例如Q?br>sprintf("pi = %.2f (approx.)',22/7)
传回的字串ؓ(f)"pi = 3.14 (approx.)"
sub(regexp, replacement,target)
在字?target 里面Q寻扄?regexp 的最ѝ最靠左边的地方Q?br>以字?replacement 代替最左边?regexp?br>例如Q?br>str = "water, water, everywhere"
sub(/at/, "ith",str)
l果字串str?x)变?br>"wither, water, everywhere"
gsub(regexp, replacement, target)
gsub 与前面的 sub cM。在字串 target 里面Q寻扄?regexp ?br>所有地方,以字?replacement 代替所有的 regexp?br>例如Q?br>str="water, water, everywhere"
gsub(/at/, "ith",str)
l果字串str?x)变?br>'wither, wither, everywhere"
substr(string, start, length)
传回字串 string 的子字串Q这个子字串的长度ؓ(f) length 个字元,
从第 start 个位|开始?br>例如Q?br>substr("washington",5,3)
传回gؓ(f)"ing"
如果 length 没有出现Q则传回的子字串是从W?start 个位|开?br>至结束?br>例如Q?br>substr("washington",5)
传回gؓ(f)"ington"
tolower(string)
字串string的大写字母改为小写字母?br>例如Q?br>tolower("MiXeD cAsE 123")
传回gؓ(f)"mixed case 123"
toupper(string)
字串string的小写字母改为大写字母?br>例如Q?br>toupper("MiXeD cAsE 123")
传回gؓ(f)"MIXED CASE 123"
8.3 输入输出的内建函?/p>
close(filename)
输入或输出的档?filename 关闭?/p>
system(command)
此函式允怋用者执行作业系l的指o(h)Q执行完毕後回?gawk
E式?br>例如Q?br>BEGIN {system("ls")}
W九(ji)?使用者定义的函式(User-defined Functions)
复杂?gawk E式常常可以使用自己定义的函式来化。呼叫?br>者定义的函式与呼叫内建函式的Ҏ(gu)一栗?br>9.1 函式定义的格?/p>
函式的定义可以放?gawk E式的Q何地斏V?/p>
一个用者定义的函式其格式如下:(x)
function name (parameter-list) {
body-of-function
}
name 是所定义的函式之名称。一个正的函式名称可包括一序列的字
母、数字、下标线 (underscores)Q但是不可用数字做开头?/p>
parameter-list 是列出函式的全部引数(argument)Q各个引C
间以逗点隔开?/p>
body-of-function 包含 gawk 的叙q?(statement)。它是函式定?br>里最重要的部份,它决定函式实际要做何U事?br>9.2 函式定义的例?/p>
下面q个例子Q会(x)每个记录的W一个栏位之值的qx与第二个
栏位之值的qx加v来?/p>
{print "sum =",SquareSum($1,$2)}
function SquareSum(x,y) {
sum=x*x+y*y
return sum
}
W十?□例
q里列?gawk E式的一些例子?/p>
gawk '{if (NF > max) max = NF}
END {print max}’
此程式会(x)印出所有输入行之中Q栏位的最大个数?/p>
gawk ‘length($0) > 80′
此程式会(x)印出一行超q?80 个字元的每一行。此处只?pattern ?br>列出Qaction 是采用内定的 print?/p>
gawk ‘NF > 0′
Ҏ(gu)拥有臛_一个栏位的所有行Q此E式皆会(x)印出。这是一个简
单的Ҏ(gu)Q将一个档案里的所有空白行删除?/p>
gawk ‘{if (NF > 0) print}’
Ҏ(gu)拥有臛_一个栏位的所有行Q此E式皆会(x)印出。这是一个简
单的Ҏ(gu)Q将一个档案里的所有空白行删除?/p>
gawk ‘BEGIN {for (i = 1; i <= 7; i++)
print int(101 * rand())}'
此程式会(x)印出□围?0 ?100 之间?7 个ؕ数倹{?/p>
ls -l files | gawk '{x += $4}; END {print "total bytes: " x}'
此程式会(x)印出所有指定的档案之bytes数目的d?/p>
expand file | gawk '{if (x < length()) x = length()}
END {print "maximum line length is " x}'
此程式会(x)指定档案里最长一行的长度印出。expand ?x)?tab ?br>?spaceQ所以是用实际的双界来做长度的比较?/p>
gawk 'BEGIN {FS = ":"}
{print $1 | "sort"}' /etc/passwd
此程式会(x)所有用者的login名称Q依照字母的序印出?/p>
gawk '{nlines++}
END {print nlines}'
此程式会(x)一个档案的总行数印出?/p>
gawk 'END {print NR}'
此程式也?x)将一个档案的总行数印出,但是计算行数的工作由gawk
来做?/p>
gawk '{print NR,$0}'
此程式印出档案的内容Ӟ?x)在每行的最前面印出行号Q它的功
能与 'cat -n' cM?br>W十一?l论
gawk Ҏ(gu)资料的处理具有很强的功能。它能够以很短的E式完成
惌做的事,甚至一或二行的E式p完成指定的工作。同L(fng)一?br>工作Q以 gawk E式来写?x)比用其它程式语a来写短很多?/p>
gawk ?GNU 所做的 awkQ它是公众Y?Public Domain) 可免费
用?br>(http://www.fanqiang.com)
原文链接Q?a >http://www.phpx.com/happy/top58375.html
1、创建及(qing)删除实例
DB2 实例 是一U逻辑上下文,DB2 命o(h)?qing)函数在其中执行。?zhn)可将实例视?f)理Ҏ(gu)据库文g的访问的服务或守护进E。在一台服务器上可定义多个实例。各实例独立于其他实例,也就是说所有实例均可分别管理、操U及(qing)调优?/p>
要在 Windows 中创建实例,只需执行以下命o(h)Q?/p>
db2icrt instance_name |
?Linux ?UNIX 中,(zhn)必d外提供一个用?IDQ用以创?fenced 用户定义的函数和存储q程q程QŞ式如下:(x)
db2icrt -u fenced_user_ID instance_name |
默认情况下,用户定义的函数和存储q程是在 fenced 模式下创建的Q因而这些进E运行在?DB2 引擎不同的地址I间中,也称为系l控制器q程 db2sysc。这为数据库理器提供了保护Q之免于被用户定义的例E意外地或恶意地破坏?/p>
要删除一个实例,首先断开所有数据库q接Q然后执行以下命令停止实例:(x)
db2idrop -f instance_name |
2、列举、迁Ud更新 DB2 实例
要列举服务器上存在的 DB2 实例Q可使用以下命o(h)Q?/p>
db2ilist |
若?zhn)军_转而用比服务器上安装?DB2 软g更新的版本,或者需要将 32 位实例迁UMؓ(f) 64 位实例,需要进行实例迁UR在Windows 上,实例q移是在必要的迁U过E中隐式完成的。在 Linux ?UNIX 上,可用以下命令显式地q移已有实例Q?/p>
db2imigr instance_name |
在ؓ(f) DB2 安装修补E序包或补丁Ӟ一旦在服务器上安装好了修补E序包,(zhn)就需要更新已有实例,以链接到新的修补E序文g。用以下命令更新实例:(x)
db2iupdt instance_name |
3、设|?DB2 环境 恰当地设|?DB2 环境非常重要Q这是因为它控制着 DB2 操作和活动的方式。DB2 环境׃下几部分构成Q?/p>
?DB2 配置文g注册?/p>
?操作pȝ环境变量
?DB2 数据库管理器配置参数
?DB2 数据库配|参?/p>
4、设|配|文件注册库
DB2 配置文g注册库是特定?DB2 的变量,它会(x)影响 DB2 pȝ的管理、配|与性能。ؓ(f)?DB2 配置文g注册库的更改生效Q?zhn)通常需要停止ƈ重启实例?/p>
要列举所支持的全?DB2 配置文g注册库:(x)
db2set -lr |
要设|?DB2 配置文g注册库:(x)
db2set registry_variable = value |
h意,在变量名、等号和变量g间没有空根{下面给Z个将 DB2COMM 注册库变量设|ؓ(f)单一值的CZQ?/p>
db2set DB2COMM=TCPIP |
?DB2COMM 注册库变量设|ؓ(f)多个值的CZ如下Q?/p>
db2set DB2COMM=TCPIP,NPIPE,LOCAL |
要将 DB2 配置文g注册库重|ؓ(f)默认|只需使用与上面相同的命o(h)卛_Q但不指定Q何|(x)
db2set registry_variable = |
要显C服务器上当前设|的所?DB2 配置文g注册库,h行以下命令:(x)
db2set -all |
5、设|系l环境变量 要了解?zhn)当前工作在哪?DB2 实例中,可运行以?DB2 命o(h)Q?/p>
db2 get instance |
此命令的输出l果形式如下Q?/p>
The current database manager instance is: DB2 |
l大多数 DB2 环境讄都是?DB2 配置文g注册库控制的。而那些未存储在配|文件注册库中的讄UCؓ(f)操作pȝ环境变量。设|系l变量的命o(h)根据?zhn)所使用的^台及(qing) UNIX shell 而有所不同?/p>
??Windows 中:(x) set DB2INSTANCE=DB2
??Linux ?UNIX ?Korn shell 中:(x) export DB2INSTANCE=DB2
DB2INSTANCE 是一个需要掌握的重要pȝ变量。它指定当前应用E序的会(x)话或H口的默?DB2 实例。一旦设|好该变量,后箋的所?DB2 命o(h)都将在该实例的作用域内执行?/p>
6、设|配|参?/p>
?DB2 中,存在两个配置 “U别”。在实例(或数据库理?U别Q?zhn)可?f)该实例配|整?DB2 环境Q这媄响实例中的所有数据库和用该实例中数据库的所有应用程序。在数据?U别Q?zhn)可配|参敎ͼ而这些参数将影响到访问特定数据库的所有应用程序的行ؓ(f)?/p>
获取 DBMS 或?DB 的配|参敎ͼ(x)
db2 get database manager configuration db2 get database configuration for database_name |
或?后同)
db2 get database manager cfg db2 get database cfg for database_name |
更改 DBMS 或?DB 的配|参?/p>
db2 update database manager configuration using parameter new_value db2 update database configuration for database_name using parameter new_value |
7、联|配|参数 l大多数配置参数均可在实例或数据库保持运行的情况下联|。只要可能,对这些联机配|参数的更改默认为立即生效。例如,若更改了 sortheap 的|所有新?SQL h用新倹{ؓ(f)昑ּ指定q种立即生效的行为,可将 immediate 关键字附加到 update 命o(h)中:(x)
db2 update database manager configuration using parameter new_value immediate db2 update database configuration for database_name using parameter new_value immediate |
若?zhn)选择此更改延迟臛_例重启或数据库激zLQ则应指?deferred 关键字:(x)
db2 update database manager configuration using parameter new_value deferred db2 update database configuration for database_name using parameter new_value deferred |
有时Q?zhn)可能希望扑և已确定ƈ延迟了哪些更攏Vؓ(f)昄数据库管理器配置参数的当前值和挂v|首先q入实例Q然后在 get database manager configuration 命o(h)中指?show detail 选项Q方法如?h意,instance_name 是系l环境变?DB2INSTANCE 讄的?Q?/p>
db2 attach to instance_name db2 get database manager configuration show detail |
同样圎ͼ要列举数据库配置参数的当前值和挂v|首先q接到数据库Q然后?show detail 选项Q?/p>
db2 connect to database_name db2 get database configuration for database_name show detail |
8、强制停止实例和数据?/p>
如果(zhn)需要数据库或数据库管理器配置更改立即生效Q而?zhn)所更改的参数ƈ非动态,那么需要停止ƈ重启数据库或整个实例。若存在q接q用此实例中一个或多个数据库的应用E序Q?zhn)无法停止ƈ重启数据库或实例。此Ӟ(zhn)可使用如下 DB2 命o(h)Q强行用户断开 与数据库的连接:(x)
db2 force application all |
(zhn)也可以在停止实例的同时断开所有用L(fng)q接Q命令如下:(x)
db2stop force |
若?zhn)只希望强制停止一个特定的应用E序Q则需要了解该应用E序的句柄?使用以下命o(h)查找句柄Q?/p>
db2 list applications |
强制停止该应用程序的q接Q可使用如下 DB2 命o(h)Q?x 应用E序句柄)
db2 force application (x) |
二、DB2 客户?服务器连通?/strong> 1、DB2 客户?服务器环?/p>
׃ DB2 用户间整体通信协议使用情况发生了变化,因此为实?DB2 客户?服务器连通性, DB2 目前支持以下协议Q?/p>
?TCP/IP ?NPIPE 对于C数据??DB2 for z/OS ??DB2 for iSeries)的连接,必须具备使用 Distributed Relational Database Architecture(DRDA)?DB2 Connect?/p>
2、ؓ(f)q程应用E序q接准备(zhn)的 DB2 数据?/p>
?DB2 客户?应用E序)能够q接到数据库之前Q?zhn)必须保服务器端通信得到了恰当的讄Q可接收q接h。要?TCP/IP q接准备服务器,(zhn)需要设|一?TCP/IP 监听器,Ҏ(gu)如下?/p>
(1)?使用以下命o(h)讄 DB2 配置文g注册?DB2COMMQ实例能够监听 TCP/IP 的连接:(x) (2)、用正的端口h新数据库理器配|参?svcenameQ如下所C:(x) (3)、数据库理器配|参?svcename q动态,因此(zhn)必d止ƈ重启实例Q以?TCP/IP 监听器启动,如下所C:(x) 3、?DB2 Configuration Assistant DB2 Configuration Assistant 提供了用户友好的向导和图形化界面Q可配置(zhn)或(zhn)的应用E序用的环境。通过 Configuration AssistantQ?zhn)可以Q?/p>
?d一个新的数据库q接 ?更新数据库连通性信?/p>
?查看q更新数据库理器配|参?/p>
?查看q更?DB2 配置文g注册?/p>
?应用程序绑定到数据?/p>
?更新 Call Level Interface(CLI)讄 4、配|数据库q通性的三种Ҏ(gu) ?DB2 Configuration Assistant 中,有三个选项可用于设|数据库q接。?zhn)可以Q?/p>
??DB2 数据库搜索网l?/p>
?使用 DB2 讉K配置文g ?手动配置q接 5、通过搜烦|络自动配置数据库连通?/p>
DB2 Discovery 搜烦q定位?zhn)的网l上?DB2 服务器,(zhn)可以选择使用搜烦 或已?发现Ҏ(gu)?/p>
搜烦Ҏ(gu)在|络中搜索Q?DB2 服务器。这U方法需要花上一些时间才能返回结果?/p>
如果(zhn)知道一些关于希望定位的 DB2 服务器的信息Q则可用已知方法,q提供数据库或服务器名称之类的信息来U束搜烦?/p>
DB2 允许某些 DB2 服务器、实例或数据库可以被发现或者不被发现?/p>
仅在 DB2 服务器上q行 Administration Server(DAS)服务、且 discover 配置参数被设|ؓ(f) search Ӟ?DB2 服务器才可被搜烦刎ͼ如下所C:(x) (zhn)还可控制哪些实例是可被发现的,只需讄 discover_inst 数据库管理器配置参数卛_Q如下所C:(x) 各数据库都拥有一个相似的配置参数 —?discover_dbQ它可启用或用数据库发玎ͼ如下所C:(x) q里要重Ҏ(gu)出,?DAS、实例或数据库别禁用发C?x)限?DB2 客户机通过其他Ҏ(gu)讄数据库连通?下文详l讨?。DB2 客户Z然可以连接到q程数据?—?即便其数据库配置 discover_db 被禁用也是如此?/p>
6、?DB2 讉K配置文g自动配置数据库连通?/p>
如果(zhn)要?1,000 台或更多的工作站讄 DB2 客户?服务器连通性,那么(zhn)会(x)怎么?(zhn)当然可以前往每一台工作站Q用Configuration Assistant 中的发现Ҏ(gu)Q但可能要花上很长一D|间才能完成这个Q务。在此类情况下,(zhn)应考虑使用 DB2 讉K配置文g?/p>
讉K配置文g中包含客h配置?DB2 服务器的q通性时所必需的信息。访问配|文件有两种cdQ?/p>
?服务器访问配|文?是在 DB2 服务器上生成的。它包含服务器上定义的全部或选定的部分实例和数据库的相关信息?/p>
?客户机配|文?是在 DB2 客户Z生成的。它包含客户Z已编目的实例(也称?和数据库的相关信息?/p>
让我们逐步地看一?DB2 讉K配置文gҎ(gu)?/p>
(1)、?Configuration Assistant 信息导出到讉K配置文g(该文件就是一?ASCII 文g)?/p>
(2)、将导出的文件发送给客户机?/p>
(3)、在客户Z使用 Configuration Assistant 文件导?DB2 客户机?/p>
W三个步骤也可以使用命o(h)实现Q?/p>
7、手动配|数据库q通?/p>
如果(zhn)了解配|连通性所必需的所有信息,那么可以使用 Configuration Assistant 中的 Add Database 向导?/p>
(1)、必首先编目节??DB2 服务?与实例的l合?/p>
(2)、编目数据库 8、列举节点和数据库目录 要在 node 目录中列举服务器与实例的l合Q可使用如下命o(h)Q?/p>
要列?database 目录Q可使用如下命o(h)Q?/p>
9、附加到实例q连接到数据?/p>
通过~目节点和数据库讄完客h/服务器连通性后Q?zhn)可附加到实例以进行实例理dQ也可连接到数据库以d该数据库中的数据或向数据库写入数据?/p>
要附加到 DB2 实例Q可使用 DB2 命o(h) attachQ如下所C:(x) 附加到实例后Q?zhn)可在该实例上执行理dQ例如:(x) ?创徏和删除数据库 ?(g)索、更新和重置数据库管理器?qing)数据库配置参?/p>
?理数据库监控程?/p>
?备䆾、还原和前滚数据?/p>
?强制用户和应用程序与实例中定义的数据库断开q接 要连接到数据库,以选择、插入、更新或删除数据Q?zhn)必须首先通过以下方式q接到数据库Q?/p>
q接到数据库之后Q就可以q行数据库的相应操作了?/p>
db2set DB2COMM=TCPIP
db2 update database manager configuration using svcename 50000
db2stop
db2start
db2admin start
db2 update admin configuration using discover search
db2 update database manager configuration using discover_inst enable
db2 update database configuration for database_name using discover_db enable
db2cfimp access_profile_name
db2 catalog tcpip node mynode remote db2server.mycompany.com server db2icdb
db2 catalog netbios node jeremy remote N01FCBE3 adapter 0
db2 catalog database sample as mysamp at node mynode
db2 catalog database baydb as newbaydb at node mynode
db2 list node directory
db2 list database directory
attach to nodename user username using password
connect to database_name user username using password
[new new_password confirm new_password ]