파일에서 줄을 읽을 때 bash 스크립트를 사용하여 주어진 문자열과 일치하는 항목을 찾으면 이전 줄을 인쇄해야 합니다.

파일에서 줄을 읽을 때 bash 스크립트를 사용하여 주어진 문자열과 일치하는 항목을 찾으면 이전 줄을 인쇄해야 합니다.

file.txt아래 내용이 포함된 파일이 있고 10000줄이 넘습니다.

Wed May 27 15:41:29 PDT 2020  
Entering directory : /aaa/bbb/ccc  
Wed May 27 15:42:30 PDT 2020  
Entering directory : /aaa/bbb/ccc/ddd  
Wed May 27 15:43:19 PDT 2020  
Entering directory : /aaa/bbb/ccc/ddd/eee  
Wed May 27 15:44:25 PDT 2020  
Leaving directory : /aaa/bbb/ccc/ddd/eee  
Wed May 27 15:45:37 PDT 2020  
Leaving directory : /aaa/bbb/ccc/ddd'  
Wed May 27 15:46:42 PDT 2020  
Leaving directory : /aaa/bbb/ccc    

나는 무엇을 해야 합니까?

디렉터리에 들어가고 나가기 전에 타임스탬프를 기준으로 어떤 디렉터리가 얼마나 많은 시간을 소비했는지 인쇄해야 합니다.

출력은 다음과 같아야합니다.

_Directory_ : `/aaa/bbb/ccc`  
_Time taken_ : `00:05:13`

이 디렉터리의 진입 시간은 다음과 같습니다. Wed May 27 15:41:29 PDT 2020출발 시간은 다음과 같습니다. Wed May 27 15:46:42 PDT 2020따라서 시차가 출력됩니다.
마찬가지로 다른 인스턴스의 디렉터리 경로와 시간 차이도 인쇄해야 합니다.

포럼에서 검색해서 받아보세요이것, 그러나 내 문제가 완전히 해결되지는 않았습니다. 나는 쉘 스크립팅 전문가는 아니지만. 따라서 누군가가 내가 출력을 얻도록 도와줄 수 있다면 좋을 것입니다.

감사해요

답변1

완전한 답변은 아니지만sed문서를 작성하는 경우

cat file.txt | sed -n 'N;l;D' | sed -n '/.*\/aaa\/bbb\/ccc\s*\$/p'

당신은 얻을 것이다

Wed May 27 15:41:29 PDT 2020  \nEntering directory : /aaa/bbb/ccc  $
Wed May 27 15:46:42 PDT 2020  \nLeaving directory : /aaa/bbb/ccc$

이는 모든 관련 디렉터리(루프오버해야 함)에 대한 전체 경로를 알고 있는 경우 문제를 단순화합니다.

경과 시간을 얻기 위한 날짜 산술이 확실하지 않지만 위에서 날짜를 추출할 수 있다면 유닉스 시간(1970년 1월 1일 이후의 초)으로 변환하는 것이 시작일 수 있습니다. 예를 들어

date -d "Wed May 27 15:41:29 PDT 2020" +%s

주어진

1590619289

따라서 스크립트에서 날짜를 변수에 넣을 수 있다면 (문자 그대로 입력하겠습니다)

ENTERDATE="Wed May 27 15:41:29 PDT 2020"
LEAVEDATE="Wed May 27 15:46:42 PDT 2020"

그리고 이를 unixtime으로 변환합니다.

ENTERSECONDS=`date -d "$ENTERDATE" +%s`
LEAVESECONDS=`date -d "$LEAVEDATE" +%s`

다음과 같이 지속 시간을 초 단위로 얻을 수 있습니다.

DURATION=$(($LEAVESECONDS - $ENTERSECONDS))

이 경우에는

313

날짜 산술을 더 잘 지원하는 패키지가 있을 수 있습니다.

도움이 되었기를 바랍니다.

답변2

GNU awk를 사용하여 원하는 작업을 수행 mktime()하고 입력에 대해 몇 가지 가정을 하는 방법은 다음과 같습니다.

$ cat tst.awk
{ gsub(/^[[:space:]]+|[[:space:]]+$/,"") }
sub(/^Entering directory : /,"") {
    enterSecs[$0] = epochSecs
    next
}
sub(/^Leaving directory : /,"") {
    deltaSecs = epochSecs - enterSecs[$0]
    delete enterSecs[$0]

    hrs  = int(deltaSecs / (60*60))
    mins = int((deltaSecs % (60*60)) / 60)
    secs = deltaSecs % 60

    printf "_Directory_ : `%s`\n", $0
    printf "_Time taken_ : `%02d:%02d:%02d`\n", hrs, mins, secs
    next
}
{
    gsub(/:/," ")
    mthNr = (index("JanFebMarAprmayJunJulAugSepOctNovDec", $2)+2) / 3
    epochSecs = mktime( sprintf("%04d %02d %02d %02d %02d %02d", $NF, mthNr, $3, $4, $5, $6) )
}

.

$ awk -f tst.awk file
_Directory_ : `/aaa/bbb/ccc/ddd/eee`
_Time taken_ : `00:01:06`
_Directory_ : `/aaa/bbb/ccc/ddd`
_Time taken_ : `00:03:07`
_Directory_ : `/aaa/bbb/ccc`
_Time taken_ : `00:05:13`

관련 정보