다른 파일의 패턴과 일치하는 모든 문자열로 파일을 생성하는 방법

다른 파일의 패턴과 일치하는 모든 문자열로 파일을 생성하는 방법

다음과 같은 파일이 있습니다.

Dir1/File1.cpp Dir2/File2.cpp \
Dir3/File1.h Dir4/File2.cpp \
Dir2/File1.cpp \
Dir2/File1.h \

다음과 같은 파일을 생성하고 싶습니다.

Dir1/File1.cpp
Dir2/File2.cpp
Dir3/File1.h
Dir4/File2.cpp
Dir2/File1.cpp
Dir2/File1.h

Bash/Sed/Awk/Grep 또는 이와 유사한 것을 사용하여 이를 수행하는 방법은 무엇입니까?

답변1

레코드 구분 기호에 대한 정규식을 지원하는 Awk가 있는 경우 RS다음과 같이 수행할 수 있습니다.

awk 'BEGIN { RS = " +| *\\\\?\\n" } 1'

이것의 장점은 전체 파일을 메모리에 저장하지 않고 일부 정규식 대체를 수행하지 않는다는 것입니다. 입력 길이는 기가바이트일 수 있습니다.

우리는 기본적으로 파일을 두 개의 레코드 구분 기호로 처리합니다. 즉, 하나 이상의 공백 또는 0개 이상의 공백과 개행 문자(선택 사항 백슬래시 앞에 올 수 있음)가 뒤따르는 것입니다.

이런 방식으로 레코드를 구분한 후 우리가 해야 할 일은 레코드를 출력하고 그 뒤에 기본 출력 레코드 구분 기호( ORS)(물론 개행 문자)가 오는 것입니다. 이는 다음으로 구성된 패턴-동작 규칙에 의해 달성됩니다 1.

또는 POSIX에 없는 것을 사용하지 않고 sed및 을 사용 하는 파이프라인 작업 :tr

tr '\n' ' ' | sed -e 's/\\//g' -e 's/ \+/ /g' | tr ' ' '\n'

줄 바꿈을 공백으로 바꾸십시오. 그런 다음 백슬래시를 제거하면서 여러 공백을 하나의 공백으로 스쿼시합니다. 그런 다음 공백을 개행 문자로 매핑합니다.

답변2

GNU와 함께grep

$ cat file 
Dir1/File1.cpp Dir2/File2.cpp \
Dir3/File1.h Dir4/File2.cpp \
Dir2/File1.cpp \
Dir2/File1.h \

$ grep -o '[^\ ]*' file 
Dir1/File1.cpp
Dir2/File2.cpp
Dir3/File1.h
Dir4/File2.cpp
Dir2/File1.cpp
Dir2/File1.h
  • -o일치하는 패턴만 추출
  • [^\ ]*0개 이상의 비공백 및 비 \문자입니다. *탐욕스럽기 때문에 가능한 한 많은 문자를 일치시키려고 시도합니다.

결과를 다른 파일에 저장하려면 다음을 사용하십시오.

$ grep -o '[^\ ]*' file > out_file


@Stéphane Chazelas가 지적했듯이 이식성을 높이기 위해 다음을 사용하는 것이 좋습니다.

grep -oE '[^\ ]+' file

여기서 -E확장 정규식을 호출하고 공백 및 문자가 [^\ ]+아닌 하나 이상과 일치합니다.\


성능 분석:

$ perl -ne 'print "$_"x100000' file > file_big
$ shuf file_big -o file_big 

$ du -sh file_big 
9.0M    file_big

비교에 사용된 의견의 모든 답변 및 제안:

$ time grep -o '[^\ ]*' file_big > o1

real    0m2.090s
user    0m2.076s
sys 0m0.016s

$ time grep -oE '[^\ ]+' file_big > o2

real    0m1.523s
user    0m1.504s
sys 0m0.012s

$ time awk 'BEGIN { RS = " +| *\\\\?\\n" } 1' file_big > o3

real    0m0.331s
user    0m0.320s
sys 0m0.008s

$ time tr -s '\\ ' '[\n*]' < file_big | grep . > o4

real    0m0.095s
user    0m0.124s
sys 0m0.008s

$ time tr '\\ ' '[\n*]' < file_big | grep . > o5

real    0m0.105s
user    0m0.104s
sys 0m0.016s

위생 검사

$ diff -s o1 o2
Files o1 and o2 are identical
$ diff -s o1 o3
Files o1 and o3 are identical
$ diff -s o1 o4
Files o1 and o4 are identical
$ diff -s o1 o5
Files o1 and o5 are identical

관련 정보