2012-06-13 5 views
4

첫 번째 발생/인스턴스를 대체하는 VI 사용은 매우 간단합니다. 여기 내 데이터를 .csv 형식/파일에 설정되어vi/vim/sed 등 모든 행에서 첫 번째 발생

:%s/search/replace/args 

하지만, :

"192.168.2.1","www.google.com","2009/01/11_10:00"," What a great website" 
"192.168.2.2/driving/is/fun","-","2009/03/22_00:00","Driving website" 
"192.168.2.4/boating/is/crazy","-","2009/03/22_00:00","Boating Website" 
"192.168.2.5","www.cars.com","2009/04/27_00:00","What a good car website" 

그래서, 당신은 4 열이있다, 첫 번째 줄에 알 수 있습니다, 이것은 이상적인 라인 .csv 형식의 경우.

그러나 두 번째 줄에는 4 개의 열이 있지만 첫 번째 열은 IP 주소 만 받아들이므로 더 이상 192.168.2.2/driving/is/fun을 제거하거나 ",".csv로 구분해야합니다 구분자. }

  • /^"\d{,3}.\d{,3 : 다음을 수행

    :/^"\d\{,3}\.\d\{,3}\.\d\{,3}\.\d\{,3}\//s/\//","/ 
    

    :

    는 VI에서, 나는 다음과 같은 사용 할 수 있었다 예를 들어, 2 행 : "192.168.2.2/

  • /"\ d {, 3}. \ d {, 3}/- 첫 번째 IP에서 검색을 시작할 고정 값을 슬래시/s /// ","/ - IP 주소의 끝에서 /를 대체하고 .csv 구분 기호로 대체 " "

이것은 VI/VIM에서 훌륭하게 작동하며, 한 번에 한 줄씩 바꿔야합니다. 그러나 데이터 세트는 훨씬 더 크며 수동으로 다음 vi 검색 및 교체를 사용하면 시간이 오래 걸립니다. VI/VIM은 한 번에 한 행씩 만 수행하므로 스크립트를 작성하거나 대체 솔루션을 찾고 있습니다. s/search/replace/g는 날짜 열을 변경하는 행의 /를 모두 바꿉니다.

과 같이 대체의 시작의 내부 전체 파일에 대한 %를 추가 :

분명히, 나는 다음과 같은 시도했습니다 내가 수정해야하는 모든 항목을 강조

:/^"\d\{,3}\.\d\{,3}\.\d\{,3}\.\d\{,3}\//%s/\//","/ 

하지만, 오류 :

E492: Not an editor command: /^"\d\{,3}\.\d\{,3}\.\d\{,3}\.\d\{,3}\//%s/\// 

다소 혼란 스럽습니다.

나는 궁극적으로 sed/perl을 사용하여 한 번에 전체 파일의 편집을 스크립팅하는 것을 좋아합니다.

.. 그래서

"192.168.2.2/ ->"192.168.2.2 ","모든 라인에

최초로 출현.

어떤 도움이 크게 감사합니다 ..

감사합니다!

+2

일반적인 프로토 타입 : 패턴을 구분하기 위해 거의 모든 문자를 사용할 수 있습니다. 예를 들어 파이프를 사용하면 슬래시를 벗어날 필요가 없습니다. – qwertyboy

답변

3

에서는 VIM, 시도 :이다

:%s/^\("\d\{,3}\.\d\{,3}\.\d\{,3}\.\d\{,3}\)\(\/[^"]\)/\1","\2 

대신 검색/대체의 I는 사용 대체 (% 라인을 지속하는 첫 번째 줄에서 1,$에 대한 바로 가기입니다) 글로벌. 검색 패턴을 대체 패턴으로 옮기고 IP 주소와 경로를 별도의 그룹으로 캡처합니다. 그런 다음 다시 뒤에서 끼 우고 ","을 끼 웁니다.

+0

멋진 작품 .. 완벽한 ... 내가 뭘 놓쳤는 지 또는 내가 추가 한 것을 설명 할 수 있습니까? – SecurettyPhreak

+0

답변에 추가했습니다. 내가 더 명확히 할 수 있는지 알려줘. – PEZ

+0

PEZ, 나는 % = global을 이해합니다. 그러나 "back squeezing"의 그룹화와 사용은 나를 위해 작동하지 않습니다. 나는 당신이 한 것을 알고 있습니다. 구문을 읽거나 사용하는 방법을 이해해야합니다.이 섹션의 작동 방식을 완전히 이해하지 못합니다. \ (\/[^ "] \)/\ 1", "\ 2 내가 IP "192.168.2.1:8080을 가지고 있고"당신 "이 :를 가진"을 대체해야만했던 것을 사용할 필요가있는 시나리오 – SecurettyPhreak

4

vi/vim에서 바꿀 검색 범위를 지정할 수 있습니다.이 경우 모든 라인에 대체 :%s 원하는 :

:%s/search/replace/g 

당신은 또한 지정할 수 있습니다

:2,5s/search/replace/g  Replace on lines 2-5 
:.,$s/search/replace/g  Replace from current line (.) to last line ($) 
:.,+3s/search/replace/g  Replace on the current line (.) and the two next lines (+3) 
:g/^asd/s/search/replace/g Replace on lines starting with 'asd'. 

그런 다음 전체 파일을 통해 사용자가 원하는 교체를 만들기 위해 간단한 패턴이 결합 할 수 있습니다 :

:%s/^\("[^/"]*\)[^"]*"/\1"/ 

이렇게하면 CSV의 첫 번째 항목에서 IP 주소 이후의 모든 항목이 제거됩니다. 이에만 IP 이후 슬래시가 그 선을 위해 수행됩니다 불구하고

:%s/^\("[^/"]*\)\/\([^"]*\)"/\1","\2/ 

는 IP 주소와 나머지에 첫 번째 항목을 분할합니다. 당신이하려고했던 것은 그 패턴을 찾아서 그 라인으로 가서 그 다음에 바꾸는 것입니다. 이 경우 '%'를 추가하면 명령이 유효하지 않게되었습니다.

+0

John Lawrence, 답장을 보내 주셔서 감사합니다. "(: % s/search/replace/g)"가 작동하지 않습니다. g - global 옵션을 사용하면 IP 끝에있는 슬래시뿐만 아니라 날짜의 슬래시도 제거합니다. 파일의 모든 슬래시가 필요합니다. : % s 만 사용하는 경우 디렉토리 경로와 날짜 등을 제거하는 줄의 모든 슬래시가 필요합니다. – SecurettyPhreak

+0

맞습니다. 'g'를 추가하면 줄의 모든 일치가 바뀌지 않고 첫 번째 일치가 바뀝니다. 그래서 내가 사용해야하는 정규 표현식에 대해 'g'를 남겨 두었습니다. 미안하지만 명확하지 않은 경우, 제 답변의 첫 번째 비트가 일반적인 참조를 위해 더 많이있었습니다. –

+0

% s/\ // ","/를 사용하더라도 슬래시가 처음으로 나오는 경우 IP에서 슬래시가없는 항목에는 슬래시가 제거되어 슬래시가 처음으로 제거됩니다 줄에있는 다른 곳의 날짜와 같습니다. – SecurettyPhreak

2

당신은 간단한 패턴으로 당신이 원하는 것을 할 수 있습니다, 라인의 경기를 시작 일치하는 그룹 시작 :

s/^\("[^/"]*\)[^"]*"/\1"/ 

이것은하는 " 일치 슬래시 수없는 문자의 수와 일치하고 "이 아니며 일치 그룹을 닫고 "이 아닌 문자를 일치시키고 "과 일치합니다. 경기 그룹의 내용에 "을 더한 것으로 바꾸십시오.

위의 패턴은 매우 간단하게 스크립트해야합니다. 다음은 파이썬 예제입니다.

#!/usr/bin/env python 
import re 
import sys 

if len(sys.argv) != 3: 
    print("Usage: log_file_cleaner <input_file> <output_file>") 
    sys.exit(1) 

pat = re.compile(r'^("[^/"]*)[^"]*"') 

with open(sys.argv[1]) as in_f, open(sys.argv[2], "w") as out_f: 
    for line in in_f: 
     line = re.sub(pat, r'\1"', line) 
     out_f.write(line) 

참고 : 당신은 할 파이썬의 최신 버전이 필요 하나이 open() 호출을 수행 with. Cygwin에서 멈추어 있다면 위의 내용을 두 개의 중첩 된 with 문장으로 편집 할 수 있습니다. 각각 하나의 open() 호출을 수행합니다.

+0

steveha, 답장을 보내 주셔서 감사합니다. s/^ \ ("[^ /"] * \) [^ "] *"/ 1 "/ ^^ 두 개의"- "사이에있는 모든 것을 강조 표시/선택합니다. 그래서 "192.168.2.1"및 "192.168.2.2/driving/is/fun"을 강조 표시합니다 – SecurettyPhreak

+0

일치 그룹이란 무엇이며 어떻게 작동하는지 이해합니까? 예, 전체 패턴이 "/ driving/is/fun"와 일치하지만 경기 그룹에서는이를 생략합니다. 그리고 첫 번째 따옴표 뒤에 공백을 제거해야하는 경우이를 수행하기 위해 패턴을 편집 할 수 있지만 예제에서는 필요하지 않음을 나타냅니다. – steveha

관련 문제