데이터 행이 포함된 로그가 있습니다.
Mon Apr 20 03:15:18 EDT 2015: my|data|data|data
로그에서 데이터를 추출하고 선행 타임스탬프를 제거하는 스크립트를 작성하려고 합니다.
while read p
do
echo $p | sed "s/.* EDT $year: //g" > replay_message_$count.txt;
count=$((count+1));
done < $fileName
이제 사용자가 매개변수를 전달 .* EDT $year:
하는 스키마를 사용하고 있습니다 .$year
연도를 매개변수로 전달하지 않고 데이터를 추출하는 방법은 무엇입니까?
답변1
날짜 형식에 항상 공백으로 구분된 6개의 필드가 있다는 것을 알고 있는 경우 다음을 사용할 수 있습니다.
cut -d ' ' -f 7-
타임스탬프가 항상 30자를 차지한다는 것을 알고 있다면 다음을 사용할 수 있습니다.
cut -c 31-
타임스탬프가 숫자, 콜론, 공백으로 끝나고 데이터에 이 패턴이 포함되지 않은 경우 다음을 사용할 수 있습니다.
sed 's/.*[0-9]: //'
더 구체적인 요구사항이 있는 경우 제출하셔도 됩니다.
답변2
while
이는 스크립트의 모든 루프를 바꾸는 것입니다 .
awk '{print substr($0, 31)>("replay_message_" NR-1 ".txt")}' file
작동 방식:
print substr($0, 31)
그러면 줄의 처음 30자를 제외한 모든 문자가 인쇄됩니다.
>("replay_message_" NR-1 ".txt")
이렇게 하면 인쇄된 내용이 줄 번호로 명명된 파일로 전송됩니다.
awk 명령이 완료되면 다음과 같은 일련의 파일이 디렉터리에 나타납니다.
$ ls -1 replay_message*
replay_message_0.txt
replay_message_1.txt
replay_message_2.txt
replay_message_3.txt
타임스탬프 길이 변화에 대한 대안
awk '{sub(/.* E[SD]T [[:digit:]]{4}: /, ""); print >("replay_message_" count++ ".txt")}' file
어떻게 작동하나요?
awk는 한 번에 한 레코드(라인)씩 암시적으로 파일을 읽습니다. 각 행에 대해 다음을 수행합니다.
sub(/.* EDT [[:digit:]]{4}: /, "")
이렇게 하면 줄 시작 부분의 타임스탬프가 제거됩니다.
정규식은 공백, 시간대(EST 또는 EDT), 공백, 연도 네 자리 숫자, 콜론 및 공백을 포함한 모든 항목과 일치합니다.
또는 타임스탬프에 30자만 필요하다고 보장되는 경우 더 간단한 대체 방법을 사용할 수 있습니다.
sub(/.{30}/, "")
입력 파일에 따라 상황에 가장 적합한 것이 무엇인지 결정해야 합니다.
print >("replay_message_" count++ ".txt")
이렇게 하면 수정된 행이 숫자가 포함된 파일에 기록됩니다
count
. 이로++
인해count
쓰기마다 증가합니다.