표준 유닉스 명령줄 도구(grep, cut, sed 등)는 모두 한 번에 한 줄씩 실행됩니다. 거의 항상 그렇습니다. 정말 좋습니다.
그러나 일부 postgresql 느린 쿼리 로그를 구문 분석하려고 합니다. 각 항목에는 시작 부분(날짜/시간, 기간)에 일부 내용이 있고 그 다음에는 SQL 쿼리가 있습니다. SQL 쿼리에는 줄 바꿈이 있을 수 있으므로 로그 파일의 각 "항목"은 1줄 이상이 될 수 있습니다. 왜냐하면 쿼리의 줄 바꿈은 이스케이프되지 않고 로그 파일에 직접 입력되기 때문입니다. 1줄 = 1로그 파일 항목이 되도록 어떤 방식으로든 이 줄을 "병합"하고 싶습니다. 이제는 항목 전체가 한 줄에 있는 경우도 있고, 항목이 최대 10줄에 걸쳐 분산되어 있는 경우도 있습니다.
이 파일을 "선형화"할 수 있는 Unix 도구가 있습니까? (PCRE) 정규 표현식을 제공하고 이를 기반으로 라인/표준 입력을 분할합니다. 이 정규 표현식 사이의 모든 실제 줄 바꿈은 "\n"
내가 지정할 수 있는 것으로 대체되어야 합니다.
Perl을 사용하여 이 작업을 수행하는 라이너가 있을 수 있지만, 내 프로그램을 만들기 전에 누군가 이미 이 프로그램을 만들었는지 확인하고 싶었습니다.
고쳐 쓰다: 샘플 데이터를 제공할 수 있지만 일반적인 질문을 알고 싶습니다. SQL Server에서는 여러 줄의 로그 파일을 생성할 수 있습니다. 모든 파일을 개행으로 구분된 unix-y 스타일 파일로 변환하는 일반적인 솔루션을 원합니다.
답변1
gawk를 사용하면 PCRE 표현식(의 하위 집합)을 레지스터 구분 기호( RS
)로 사용하고, 다른 출력 레지스터 구분 기호( ORS
)를 정의하고 이를 바꿀 수 있습니다 \n
.
예:
gawk 'BEGIN {RS="[ ]*;\n"; ORS="\n===\n"}
{gsub("\n","\\n"); print} '
이 예에서는 다음과 같습니다.
[ ]*;\n
레지스터는 입력에서 다음과 같이 구분됩니다.- 레지스터는 출력에서 "\n===\n"으로 구분됩니다.
답변2
로그 파일을 한 줄씩 구문 분석하고 모든 \n을 억제합니다. 처음 항목을 제외하고 새 항목이 표시되면 먼저 \n을 쓰세요.
말씀하셨는데 Each entry has some stuff at the start (datetime, duration)
예를 들지 않으셨네요. 알겠습니다. 이름을 NEW_ENTRY로 하겠습니다. 변경하시면 됩니다.
inStatement=0
cat logfile | while read -r line; do
if [[ ${inStatement} = 0 ]]; then
inStatement=1
else
[[ ${line} = NEW_ENTRY* ]] && echo
fi
echo -n "${line} "
done
echo