저장소와 일치하고 정보를 표준 입력으로 반환합니다.

저장소와 일치하고 정보를 표준 입력으로 반환합니다.

그래서 저는 정말 여기에 갇혀 있어요. 다음 형식의 수백만 행의 데이터가 포함된 일부 파일을 얻었습니다.

username|process name|process time (in minutes)

거의 340만 개의 데이터 행이 있습니다. 이제 내 임무는 이 모든 데이터를 빠르게 탐색할 수 있는 스크립트를 작성하는 것입니다.

따라서 기본적으로 명령줄에서 사용자 이름을 입력하고 해당 사용자 이름에 대한 모든 데이터 행을 추출하여 추가한 다음 표시하려고 합니다. 이 사용자의 총 처리 시간 및 이 사용자의 총 프로세스 수와 같은 의미입니다.

이것이 내가 지금까지 갖고 있는 것인데 많지는 않다.

tput cup 19 10
read -p "Please Enter a UserName: " uname

그게 내가 가진 전부입니다. 내가 어떻게 할 수 있는지 아는 사람 있나요?

답변1

이것을 예시 입력 파일로 사용해 보겠습니다.

$ cat file
jim|process1|23
bob|process2|5
jim|process3|7

awk를 사용하세요

이제 다음 쉘 스크립트를 작성해 보겠습니다.

$ cat script.sh
#!/bin/sh
read -p "Please Enter a UserName: " uname
awk -v n="$uname" -F\| '$1==n{total+=$3} END{printf "Total for %s is %s minutes\n",n,total}' file

예를 들어, Jim이 사용하는 시간을 요약해 보겠습니다.

$ sh script.sh
Please Enter a UserName: jim
Total for jim is 30 minutes

어떻게 작동하나요?

awk는 입력 파일의 각 행을 암시적으로 반복합니다. 스크립트는 n사용자 이름과 total사용자가 사용한 총 시간(분) 이라는 두 가지 변수를 사용합니다 n.

  • -v n="$uname"

    그러면 awk 변수가 생성되고 n여기에 쉘 변수의 값이 할당됩니다 uname.

  • -F\|

    이는 awk에게 |필드 구분 기호 로 사용하도록 지시합니다.

  • $1==n{total+=$3}

    첫 번째 필드가 $1사용자 이름과 일치할 때마다 세 번째 필드의 양만큼 n합계가 늘어납니다 .total$3

  • END{printf "Total for %s is %s minutes\n",n,total}

    파일 읽기가 끝나면 결과를 인쇄합니다.

쉘을 사용하다

또는 쉘에서 루프를 수행할 수 있습니다.

$ cat script2.sh 
#!/bin/sh
read -p "Please Enter a UserName: " uname
while IFS=\| read -r name process minutes; do
    [ "$name" = "$uname" ] && total=$((total+minutes))
done <file
echo "Total for $uname is $total minutes"

데모로:

$ sh script2.sh
Please Enter a UserName: jim
Total for jim is 30 minutes

두 방법 모두 시간을 재지는 않았지만 이 방법이 awk더 빠를 것으로 예상됩니다.

관련 정보