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

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

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

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

레코드 구분 기호 regex를 지원하는 Awk가 있는 경우 RS다음을 수행할 수 있습니다.

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

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

우리는 기본적으로 파일을 두 개의 레코드 구분 기호로 처리합니다. 하나 이상의 공백 또는 0개 이상의 공백과 개행 문자 앞에 선택적 백슬래시가 올 수 있습니다.

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

sed또는 배관을 사용하고 trPOSIX에 존재하지 않는 것을 사용하지 마십시오.

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

관련 정보