![단일 라인 매개변수를 기반으로 텍스트 파일에서 라인 추출](https://linux55.com/image/114490/%EB%8B%A8%EC%9D%BC%20%EB%9D%BC%EC%9D%B8%20%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98%EB%A5%BC%20%EA%B8%B0%EB%B0%98%EC%9C%BC%EB%A1%9C%20%ED%85%8D%EC%8A%A4%ED%8A%B8%20%ED%8C%8C%EC%9D%BC%EC%97%90%EC%84%9C%20%EB%9D%BC%EC%9D%B8%20%EC%B6%94%EC%B6%9C.png)
저는 스크립팅을 처음 접했기 때문에 도움을 주시면 감사하겠습니다. 어떤 경우에는 상당히 길 수 있는 텍스트 파일이 있는데, 텍스트 줄의 각 부분 길이는 약 6/7줄입니다. 이는 로그 파일이며 각 섹션은 타임스탬프라는 단어로 시작됩니다. 각 줄 사이에는 빈 줄이 있습니다. 각 프로필 줄은 세미콜론으로 끝납니다.
timestamp=201706291035.....;
line 2;
line 3;
line 4;
line 5;
line 6;
line 7;
timestamp=201706291038.....;
line 2;
line 3;
line 4;
line 5;
line 6;
한 줄의 각 섹션을 다른 텍스트 파일로 추출할 수 있어야 합니다. 마지막 세미콜론 없이 사용하는 것이 좋습니다.
timestamp=201706291035.....;line 2;line 3;line 4;line 5;line 6;line 7
timestamp=201706291038.....;line 2;line 3;line 4;line 5;line 6
이 정보가 해결책을 찾는 데 충분합니까?
다음은 간단한 예입니다.
타임 스탬프=2017-06-28-01.01.35.080576;
사용자 ID=user1
; 애플리케이션
ID=10.10.10.10.11111.12345678901;
타임 스탬프 = 2017-06-28-01.01.36.096486;
사용자 ID = user1
; 애플리케이션
ID = 10.10.10.10.11111.12345678901 ; table.field, table.field 여기서 table.field = 값
@steeldriver 스크립트를 실행한 후 소스 파일과 대상 파일이 동일하게 보입니다.
답변1
이는 다음과 같이 관용적 awk를 사용하여 수행할 수 있습니다.
awk '$1=$1' RS= OFS= infile
산출:
timestamp=201706291035.....;line 2;line 3;line 4;line 5;line 6;line 7;
timestamp=201706291038.....;line 2;line 3;line 4;line 5;line 6;
설명하다
여기에는 많은 것이 담겨 있습니다. 기본적으로 세 가지 단계가 있습니다.
RS
먼저, 입력은 레코드 구분 기호( )를 기준으로 레코드로 분할됩니다.- 각 레코드는 필드 구분 기호(
FS
)를 기준으로 여러 필드로 분할됩니다. - 인쇄할 때 출력 필드 구분 기호(
OFS
)가 필드 구분 기호로 사용됩니다.
awk가 입력을 구문 분석할 때 몇 가지 암시적 규칙이 적용됩니다. 데이터는 레코드별로 구분되어 한 번에 한 레코드씩 읽혀집니다 RS
(기본값은 \n
). RS
위의 예와 같이 비어 있으면 빈 줄로 레코드가 구분됩니다. 따라서 각 부분은 레코드로 읽혀집니다.
강제 로 awk
교체 하려면 첫 번째 필드를 그 자체로 설정합니다 .FS
OFS
$1
편집하다
지적한대로강철 드라이버, OP는 후행 세미콜론을 제거하려고 합니다. 뻔뻔한 표절:
awk '{ sub(/;$/,"",$NF); $1=$1 } 1' RS= OFS= infile
답변2
이는 다음을 통해 수행할 수 있습니다.
perl -lF';\n?' -00ne '$,=";"; print @F' yourfile
산출
timestamp=201706291035.....;line 2;line 3;line 4;line 5;line 6;line 7
timestamp=201706291038.....;line 2;line 3;line 4;line 5;line 6
피복재
펄 옵션
a)
-l
=> ORS="\n" + RS = "\n"b)
-F';\n?'
=>는 FS를 세미콜론으로 만들고 그 뒤에 선택적 개행 문자가 옵니다.c)
-00
=>는 RS=를 만들어 단락 모드를 활성화합니다.d)
-n
=> 암시적 파일 읽기 + 명시적 인쇄가 활성화됩니다.메인 : 현재 레코드에 따라 구분된 필드
$,=;
인 OFS에 세미콜론이 추가됩니다 .@F
$_
FS
답변3
타임스탬프 앞에 빈 줄이 있으면 간단한
perl -pe 'chomp unless /^$/'
개행 문자가 없으면 이전 줄을 기억해야 합니다.
perl -pe 'chomp; print "\n" if $. > 1 && /^timestamp=/; print }{ print "\n"'
답변4
그냥 이런 방법이니까sed
이 문장을 출발점으로 삼으세요Peter Krumins의 Sed 전문 용어 설명, 1부: 파일 간격, 번호 매기기, 텍스트 변환 및 교체
행이 백슬래시 "\"로 끝나면 다음 행에 추가됩니다.
sed -e :a -e '/\\$/N; s/\\\n//; ta'
첫 번째 표현식 ':a'는 이름이 지정된 레이블 "a"를 만듭니다. 두 번째 표현식은 현재 줄이 백슬래시 "\"로 끝나는지 확인합니다. 존재하는 경우 "N" 명령을 사용하여 다음 행과 연결됩니다. 그런 다음 "s/\\n//" 명령을 사용하여 연결 줄 사이의 슬래시와 줄 바꿈을 제거합니다. 교체가 성공하면 표현식의 시작 부분으로 분기하고 또 다른 백슬래시가 있을 수 있기를 바라면서 동일한 작업을 다시 수행합니다. 교체에 실패하면 줄이 백슬래시로 끝나지 않고 인쇄됩니다.
선행 공백을 유지하되 제거하기 위해 교체를 교체 하고 조정하면 \\
다음과 같은 결과를 얻을 수 있습니다.;
;
$ sed -e :a -e '/;$/N; s/\n *//; ta' infile
timestamp=201706291035.....;line 2;line 3;line 4;line 5;line 6;line 7;
timestamp=201706291038.....;line 2;line 3;line 4;line 5;line 6;
폐쇄! 이제 빈 줄을 짜내려고 합니다. 패턴을 테스트하여 이를 수행할 수 있습니다.마치다개행(즉, 추가된 행이 비어 있음)에서 다음과 같은 경우 인쇄합니다.에 따라개행 후 패턴 삭제:
$ sed -e :a -e '/;$/N; /\n$/{P;d;}; s/\n *//; ta' infile
timestamp=201706291035.....;line 2;line 3;line 4;line 5;line 6;line 7;
timestamp=201706291038.....;line 2;line 3;line 4;line 5;line 6;
이제 우리는 뒤에 오는 것들을 잘라내기만 하면 됩니다 ;
. 이를 수행하는 한 가지 방법은 패턴 공간에 추가할 때 각 줄을 삭제한 ;
다음 개행을 삭제하면서 다시 삽입하는 것입니다.
$ sed -e :a -e '/;$/{s///;N;}; /\n$/{P;d;}; s/\n */;/; ta' infile
timestamp=201706291035.....;line 2;line 3;line 4;line 5;line 6;line 7
timestamp=201706291038.....;line 2;line 3;line 4;line 5;line 6
우리가 이미 개행 문자를 먹었기 때문에 마지막 항목은 ;
다시 삽입되지 않으므로 {P;d;}
대체 항목이 s//\n /;/
적용되지 않습니다.