本人想把一个几万行的txt文件内的,某些行删除,手工太慢。想把带有某些字符(比如一个单词)的行全部删除。操作以后保存退出。
请问用到什么方法?
循环读取文件内容,每次读1行或10行,行数随便,然后字符串查找,找到了就删除,把剩下的追加到临时文件里,最后替换原来的文件。
用脚本语言处理吧,两三行代码搞定。
比如:perl
fgets()一行一行读文件,一行一行处理,再把处理结构写入新文件。
完成后,关闭新,老文件。删除老文件,最后把新文件改名为老文件。
把分给我吧, 正好写过一个过滤的应用
- #include "stdafx.h"
- #include
- #include
- #pragma warning(disable:4244 4267)
- ////////////////////////////////////////////////////////////////////////////////////////////////////////
- template struct Str_LookupA; // ANSI字符集字符串查找模板
- template struct Str_LookupW; // UNICODE 字符集字串查找模板
- template struct Str_Filter_Word; // 字符串过滤模板框架 -- 只过滤输入单词
- template struct Str_Filter_Line; // 字符串过滤模板框架 -- 过滤包含输入单词段落
- ////////////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // 模板参数 t_fMatch, 指明查找字串是否区分大小写。
- // t_fMatch = true,查找函数将不区分大小写
- // t_fMatch = false, 默认方式,按照输入查找字串进行匹配
- //
- template struct Str_LookupA
- {
- enum { TYPE_SIZE = sizeof(CHAR)};
- typedef CHAR* _Type;
- typedef const CHAR* _constType;
- typedef _Type _ReturnType;
- _ReturnType operator()(_Type pSrc,_constType pSearch)
- {
- return t_fMatch ? StrStrIA(pSrc,pSearch) : StrStrA(pSrc,pSearch);
- }
- _ReturnType LineStart(_Type pSrc,_Type pLast)
- {
- _Type pStart = StrRStrIA(pSrc,pLast,"\r\n");
- return pStart ? pStart + 2 : pSrc;
- }
- _ReturnType LineEnd(_Type pSrc)
- {
- _Type pEnd = StrStrA(pSrc,"\r\n");
- return pEnd ? pEnd + 2 : NULL;
- }
- DWORD Length(_constType pStr)
- {
- return lstrlenA(pStr);
- }
- };
- template struct Str_LookupW
- {
- enum { TYPE_SIZE = sizeof(WCHAR)};
- typedef WCHAR* _Type;
- typedef _Type _ReturnType;
- typedef const WCHAR* _constType;
- _ReturnType operator()(_Type pSrc, _constType pSearch)
- {
- return t_fMatch ? StrStrIW(pSrc,pSearch) : StrStrW(pSrc,pSearch);
- }
- _ReturnType LineStart(_Type pSrc,_Type pLast)
- {
- _Type pStart = StrRStrIW(pSrc,pLast,L"\r\n");
- return pStart ? pStart + 2 : pSrc;
- }
- _ReturnType LineEnd(_Type pSrc)
- {
- _Type pEnd = StrStrW(pSrc,L"\r\n");
- return pEnd ? pEnd + 2 : NULL;
- }
- DWORD Length(_constType pStr)
- {
- return lstrlenW(pStr);
- }
- };
- template >
- struct Str_Filter_Word
- {
- typedef typename _RT::_Type _Type;
- typedef typename _RT::_constType _constType;
- typedef typename _RT::_ReturnType _ReturnType;
- _ReturnType operator()(_Type pBuffer, DWORD cbSize, _constType *pWord, DWORD cbCount, DWORD* pcbRemoved = NULL)
- {
- ATLASSERT(pBuffer && pWord && cbSize && cbCount);
- _RT Str_Lookup;
- DWORD dwRemoved = 0;
- DWORD cbStart = 0;
- DWORD cbEnd = cbSize;
- for (DWORD i = 0; i < cbCount; i++)
- {
- _Type pStart = pBuffer;
- _Type pEnd = pBuffer + cbEnd;
- _constType pSearch = pWord[i];
- DWORD cbLength = Str_Lookup.Length(pSearch);
- if (!pSearch)
- break;
- for (;;)
- {
- _Type p = Str_Lookup(pStart,pSearch);
- if (!p) break;
- dwRemoved++;
- _Type pNext = p + cbLength;
- if (pNext && pNext <=pEnd)
- {
- cbStart = p - pBuffer;
- memmove(p,pNext,_RT::TYPE_SIZE * (cbEnd - cbStart));
- pStart = p;
- cbEnd -= cbLength;
- }
- else
- {
- memset(pStart,0, _RT::TYPE_SIZE * (cbEnd - cbStart));
- break;
- }
- }
- }
- if (pcbRemoved) *pcbRemoved = dwRemoved;
- return pBuffer;
- }
- _ReturnType operator()(_Type pBuffer, DWORD cbSize, _constType pWord, DWORD* pcbRemoved = NULL)
- {
- _constType pWords[] = {pWord,0};
- return operator()(pBuffer,cbSize,pWords,1,pcbRemoved);
- }
- };
- template >
- struct Str_Filter_Line
- {
- typedef typename _RT::_Type _Type;
- typedef typename _RT::_constType _constType;
- typedef typename _RT::_ReturnType _ReturnType;
- _ReturnType operator()(_Type pBuffer, DWORD cbSize, _constType *pWord, DWORD cbCount, DWORD* pcbRemoved = NULL)
- {
- ATLASSERT(pBuffer && pWord && cbSize && cbCount);
- _RT Str_Lookup;
- DWORD dwRemoved = 0;
- DWORD cbStart = 0;
- DWORD cbEnd = cbSize;
- for (DWORD i = 0; i < cbCount; i++)
- {
- _Type pStart = pBuffer;
- _Type pEnd = pBuffer + cbEnd;
- _constType pSearch = pWord[i];
- if (!pSearch) break;
- for (;;)
- {
- _Type p = Str_Lookup(pStart,pSearch);
- if (!p) break;
- dwRemoved++;
- pStart = Str_Lookup.LineStart(pBuffer,p);
- _Type pLineEnd = Str_Lookup.LineEnd(p);
- if (pLineEnd)
- {
- cbStart = pStart - pBuffer;
- memmove(pStart,pLineEnd,_RT::TYPE_SIZE * (cbEnd - cbStart));
- cbEnd -= (pLineEnd - pStart);
- }
- else
- {
- memset(pStart,0, _RT::TYPE_SIZE * (cbEnd - cbStart));
- break;
- }
- }
- }
- if (pcbRemoved) *pcbRemoved = dwRemoved;
- return pBuffer;
- }
- _ReturnType operator()(_Type pBuffer, DWORD cbSize, _constType pWord, DWORD* pcbRemoved = NULL)
- {
- _constType pWords[] = {pWord,0};
- return operator()(pBuffer,cbSize,pWords,1,pcbRemoved);
- }
- };
- HRESULT test_file_filter(LPCTSTR lpszFile, LPCSTR *pWords, DWORD cbWords, bool fLine = false)
- {
- ATL::CAtlFileMapping map;
- ATL::CAtlFile file;
- HRESULT hr;
- ULONGLONG uSize = 0;
- if (FAILED(hr = file.Create(lpszFile,GENERIC_READ | GENERIC_WRITE,0,OPEN_EXISTING)))
- return hr;
- if (FAILED(hr = file.GetSize(uSize)))
- return hr;
- size_t nSize = (size_t)uSize;
- if (FAILED(hr = map.MapFile(file.m_h,nSize,0,PAGE_READWRITE,FILE_MAP_READ | FILE_MAP_WRITE)))
- return hr;
-
- LPSTR pData = (LPSTR)map.GetData();
- DWORD cbRemoved = 0;
- if (fLine)
- {
- // 区分大小写, 过滤包含指定单词的段落
- Str_Filter_Line<> filter;
- filter(pData,nSize,pWords,cbWords,&cbRemoved);
- }
- else
- {
- // 以不区分大小写的模式,过滤指定单词
- Str_Filter_Word filter;
- filter(pData,nSize,pWords,cbWords,&cbRemoved);
- }
- printf(pData);
- return S_OK;
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- // 过滤指定文件中多个单词
- LPCSTR pWords[] = {"Sec","Time","北国","sample","for",0};
- HRESULT hr = test_file_filter(_T("c:\\100.txt"),pWords,5);
- if (FAILED(hr))
- printf("failed! hr = 0x08X\n",hr);
- // 过滤文件中包含指定单词的段落
- hr = test_file_filter(_T("c:\\300.txt"),pWords,5,true);
- if (FAILED(hr))
- printf("failed! hr = 0x08X\n",hr);
- _getch();
- return 0;
- }
5楼的同学,我把你的代码用VC6编译,提示文件无法编译。是不是要建一个工程,要建什么类型的?
一句搞定
sed -e '/hello/p' test.c > test.c
hello替换为你要查找的单词
test.c为目标文件。
测试工程师用VS2005写的。里边测试代码中用了 atlfile.h 这个头文件,这个头文件在VC7以上才有,所以你在VC6中无法编译。 过滤部分在VC6下应该能编译通过。
引用: 引用 9 楼 bdzwj 的回复:
测试工程师用VS2005写的。里边测试代码中用了 atlfile.h 这个头文件,这个头文件在VC7以上才有,所以你在VC6中无法编译。 过滤部分在VC6下应该能编译通过。
那你能否编译好生成一个exe文件发给我一个,谢谢
我的目的是,把一个几万行的文本文件找出几百行需要的行,其余的删除。只要某行包含&com就留下,或者只要&txt 。。就删除
sed -e '/&txt/d' filename
cat filename | grep \&com
如果你使用Windows平台,建议装一个ActivePerl,处理类似的问题,极为方便。
引用: 引用 12 楼 hzcpig 的回复:
sed -e '/&txt/d' filename
cat filename | grep \&com
这个是什么语句?dos?
引用: 引用 8 楼 hzcpig 的回复:
一句搞定
sed -e '/hello/p' test.c > test.c
hello替换为你要查找的单词
test.c为目标文件。
高手啊
额~~~抱歉,没注意到这个不是linux环境,那句是linux shell下sed工具。sed是一个专门进行行处理的工具。
不过windows下同样有 sed for windows工具。