기본적으로 다음과 같은 로그 항목을 보고 있습니다.
*** Send Command has completed Successfully
Transmitted 508200 bytes in 1 seconds
File Transfer Complete
RemoteTransactionNumber is ***********
************Server: Transfer Mode Set To Send
: *********************************************************50 al**********b:Y
lf:"*********************************************************" rf:"*************
*(+1)" **************************************41
2017/04/18 13:05:32 About to execute the following Send command:
$LOGGER 변수를 정의하고 로그된 데이터를 원격 서버에 있는 그대로 저장했습니다. 또한 $currentdate라는 변수를 만들고 저장했습니다.
currentdate=$(date +"%Y/%m/%d/ %I")
그래서 제가 이 질문을 한 현재 시간은 2017/04/19/01 입니다.
"명령 보내기가 성공적으로 완료됨"과 일치시키고 싶다고 가정하고 다음을 수행했습니다.
ALERT=$(echo "$LOGGER" | awk "/Send Command has completed Successfully/" | grep -A 12 $currentdate)
그런 다음 일치하는 전송이 최신인지 확인하기 위해 현재 날짜와 시간(최대 1시간)을 찾기 위해 앞으로 12줄을 grep하려고 합니다. 왜냐하면 이것이 이 스크립트가 실행될 때 내가 관심을 갖는 전부이기 때문입니다.
그러나 마지막 awk | grep -A 12 명령은 작동하지 않습니다. awk 일치를 누른 후 날짜를 찾고 $currentdate와 일치하는지 확인하는 방법에 대한 아이디어가 있습니까? 이 작업은 모두 SSH pass 명령에서 로그 가져오기를 검색한 후 로컬 변수(FYI)에서 수행되므로 이 시점에서는 실제 파일이 조작되지 않습니다.
편집: 따라서 여기서 하려는 작업을 수행하는 이유를 더 명확하게 하기 위해 현재 시간에 대한 모든 일치 항목을 보고해야 합니다. 그리고 날짜는 "Sent Successly" 항목의 12줄 이내입니다. 실제로 SSH를 사용하여 원격으로 서버에 액세스하고 지난 시간에 작성된 로그 파일 수를 가져오고 있습니다. 그런 다음 각 행의 마지막 100개 행을 가져와서 다음과 같이 $Logger 변수에 저장합니다.
COMMAND1="find /xxy -mmin -60 | wc -l"
FILENUM=`/xxy-1.05/sshpass -p$PASS ssh -q -o StrictHostKeyChecking=no -o
ConnectTimeout=310 $USER@$HOST "$COMMAND1"
COMMAND2="find /xxy -mmin -60 | tail -n $FILENUM | xargs tail -n100"
LOGGER=`/xxy-1.05/sshpass -p$PASS ssh -q -o StrictHostKeyChecking=no -o
ConnectTimeout=310 $USER@$HOST "$COMMAND2"
따라서 각 게임의 날짜를 확인해야 한다는 점을 고려하면 변수에 깔끔하게 저장하는 것이 가장 좋은 방법인지 잘 모르겠습니다(awk가 이 작업을 수행하는 경향이 있으며 이것이 제가 첫 번째 선택인 이유)
답변1
뭔가가 작동하지 않으면, 그것을 분해하고 여러 부분이 어떤 역할을 하는지 살펴보고 무엇이 잘못되었는지 알아내야 합니다. 다음 명령을 시도해 보세요.
echo "$LOGGER" | awk "/Send Command has completed Successfully/"
당신은 무엇을 얻나요? 그냥 *** Send Command has completed Successfully
라인. 물론 날짜에 대한 검색은 작동하지 않습니다. 행에 날짜가 포함되어 있지 않습니다.
awk 솔루션을 원한다면 다음과 같이 시도해보십시오.
echo "$LOGGER" | awk -vc="$currentdate" '
/Send Command has completed Successfully/ { flag1=1 }
$0 ~ c { flag2=1 }
END { if (flag1 && flag2) print "Yes"; else print "No" }'
currentdate
쉘 변수를 awk 변수로 awk에 전달한 다음 해당 c
변수와 "Send Command..." 문자열이 입력에 있는지 확인합니다.
그런데,
"$currentdate"
타당한 이유가 없고 수행 중인 작업을 확실히 알고 있지 않는 한 항상 쉘 변수 참조(예: )를 인용해야 합니다 . 공백이 있는 한grep … $currentdate
명령은 따옴표 없이는 작동하지 않습니다."$currentdate"
로그 항목이 최신인지 확인하려는 경우 명령
%I
에서 이 명령을 사용하면 안 됩니다date
. 이는 01..12 범위의 시간을 반환합니다. 그래서,- 로그 항목이 오전 1시(따라서 "
2017/04/18 01:##:## About to execute the following Send command:…
")이고 현재 시간이 오후 1시인$currentdate
경우 변수2017/04/18 01
는 12시간 전의 메시지가 현재 메시지임을 표시하지만 - 귀하의 예에서와 같이 로그 항목이 오후 1시부터이고(따라서 "
2017/04/18 13:05:32 About to execute the following Send command:…
") 현재 시간이 오후 1시인 경우$currentdate
변수는 (다시)2017/04/18 01
이므로 현재 메시지가 현재 메시지가 아님을 의미합니다.
를 사용해야 하며
%H
범위는 (00..23)입니다.- 로그 항목이 오전 1시(따라서 "
답변2
편집: 로거의 날짜 순서가 확실하지 않은 것 같아서 "Anywhere"의 날짜와 일치하도록 항목을 변경했습니다.
귀하의 예에는 여러 항목이 표시되지 않으므로 다음과 같다고 가정합니다.
2017/04/....
(several lines)
*** Send Command has completed Successfully
2017/04/.... (another time, maybe before or after, no ordering )
(several lines)
2017/04/.... (another time, maybe before or after, no ordering )
(several lines)
2017/04/.... (another time, maybe before or after, no ordering )
(several lines)
2017/04/.... (another time, maybe before or after, no ordering )
(several lines)
*** Send Command has completed Successfully
2017/04/.... (another time, maybe before or after, no ordering )
(several lines)
2017/04/.... (another time, maybe before or after, no ordering )
나는 당신에게만 필요하다고 믿습니다 :
dateappearsas="^[0-9][0-9][0-9][0-9]/[0-9][0-9]/"
looking_for="Send Command has completed Successfully"
echo "$LOGGER" \
| egrep -i "${dateappearsas}|${looking_for}" \
| grep -i -B 1 "${looking_for}" \
| grep -A 1 "$currentdate"
returncode="$?" # in bash, gets the latest command in the preceding pipe, ie the grep's exit code
# the egrep: outputs all dates, and interspered among those some "successfully"
# the 2nd grep: transform those into pairs of date & successfully
# the last grep find only the matching currentdate and the line after it
if [ "$returncode" = "0" ]
then
echo "There is a transfer that matches the current date, AND was successful"
else
echo "There is either no date matching the current date, or it wasn't successfull"
fi
기본적으로 egrep은 찾고 있는 콘텐츠와 컨텍스트를 가져옵니다(여기서는 날짜). 아마도 몇 줄의 컨텍스트를 제공할 것이며, 그 중 일부는 여러분이 찾고 있는 내용도 포함하고 있습니다. 그런 다음 grep -B 1 'what your are looking for'
context/lookedfor 쌍을 함께 그룹화하고(찾은 행과 이전 날짜를 함께 배치) 마지막으로 현재 날짜가 이 쌍에 있는지 찾기 위한 grep을 수행합니다.