루프 및 변수를 읽는 동안

루프 및 변수를 읽는 동안

나는 당신의 협의회를 찾고 있습니다..배시 스크립트에서..벽에 부딪혔기 때문입니다.

주어진 파일의 모든 라인을 배열로 읽고 일련의 명령문을 실행하여 해당 매개변수가 true인지 false인지 확인하고 싶습니다.

다음은 각 줄의 값을 배열로 추출하는 것과 같은 파일 ID의 예입니다.

2019-11-07 10:07:08,000 p=28290 u=root |  ansclient2                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
2019-11-07 12:48:42,438 p=1830 u=root |  ansclient                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

그래서 노력 중이에요 -

while read -r row ; do
    args=${row[@]}
    #pid
    pc=${row[2]}
    #hostname
    hn=${row[5]}
    #failed row
    st=${row[10]}
    echo $pc
    echo $hn
    echo $st
    if [ $st -eq "failed=0" ] ; then echo "true" 
    else
        echo "failed is something other than 0"
        echo $hn $st
    fi

예상대로 작동하지 않습니다. [true인 경우] 각 행을 배열로 반복하고 'failed=' 값을 비교하여 0인지 다른 값인지 확인하고 싶습니다.

누구든지 도움을 주실 수 있다면 정말 감사하겠습니다..

미리 감사드립니다

답변1

이러한 파일을 읽으려면 다음을 사용하는 것이 좋습니다 awk.

awk '{
    print $3
    print $6
    print $11
    if ($11 == "failed=0") print "true"
    else print "failed is something other than 0"
}' file

답변2

@pLumo가 말했듯 awk이 이것은 단지 인쇄하려는 경우 더 나은 도구입니다. 이러한 변수를 사용하여 다른 멋진 작업을 수행하고 이를 bash 스크립트에서 사용해야 하는 경우 read배열을 직접 읽도록 명령을 수정하는 것이 좋습니다.

row전체 행(variables )과 배열(variables ) 이 필요한 경우 args다음과 같이 작성할 수 있습니다.

while IFS= read -r row; do
  read -r -a args <<< "$row"
  # ...
done

기본적으로 IFS모든 공간으로 설정되어 있습니다. 입력이 세미콜론으로 구분된 열이 있는 CSV 파일인 경우 IFS이에 따라 이를 설정할 수 있습니다.

while IFS= read -r row; do
  IFS=';' read -r -a args <<< "$row"
  # ...
done

답변3

pLumo의 답변으로 판단하면 - 이것이 내가 선택한 것입니다 -

#!/bin/bash


#transform the log
grep -i recap -A1 ansible.log |grep -iv recap |grep -v "\-\-" > ansible2.log

#get status of output of said ansible2.log with a success status along with the hostname
#of the job

awk '{print $3, $6, $10, $11
if ($10 == "unreachable=0") print "DEVICE WAS REACHABLE 0"
else if($10 != "unreachable=0") print "DEVICE WAS UNREACHABLE 1"

if ($10 == "unreachable=0")
if ($11 == "failed=0") print "NOTHING FAILED, was successful run"
else print $11 " is something other than 0"
else print $10 " was unreachable" }' ansible2.log

또한 rexkogitans 방법을 사용하고 싶지만 IFS제대로 작동하지 않습니다. .
IFS가 로그를 한 줄씩 읽어서 반복할 수 있도록 값을 채우려고 합니다. 대신 내 코드는 무한히 반복되거나 변수를 올바르게 채우지 않습니다. (

이 코드에서 많은 출력을 얻습니다. [4줄 로그 파일의 112줄과 같습니다. 정확할 수 없습니다! ]

#!/bin/bash

while IFS='' read -r line 
do 
for i in $line
do
echo "pid is $i ${os[1]} , host is $i ${os[2]}, success is $i ${os[3]}, failed is $i ${os[4]}"
echo "done for that line"
done
done <ans.log

예를 들어, 다음과 같은 출력을 얻습니다.

pid is 2019-11-07  , host is 2019-11-07 , success is 2019-11-07 , failed is 2019-11-07 
done for that line
pid is 10:07:08,000  , host is 10:07:08,000 , success is 10:07:08,000 , failed is 10:07:08,000 
done for that line
pid is p=28290  , host is p=28290 , success is p=28290 , failed is p=28290 
done for that line
pid is u=root  , host is u=root , success is u=root , failed is u=root 
done for that line
pid is |  , host is | , success is | , failed is | 

변수를 올바르게 채우지 못하고 대신
올바르게 호출하는 대신 한 번에 하나씩 반복하는 것 같습니다. 어떤 아이디어가 있습니까?

모든 도움에 감사드립니다. 더 빨리 답변하지 못해 죄송합니다. 테스트도 필요하고 밤새도록 시스템 관리자 작업을 했습니다.

고마워요, =-브라이언

관련 정보