편집: 죄송합니다. 제가 주장한 결과가 잘못되었습니다. 이전에 생각했던 것보다 더 많은 공백이 있습니다(이러한 공백을 제거하기 위해 출력을 html 파일에 저장했을 때 문제가 발생했습니다). 실제 출력은 다음과 같습니다.
user@Debian:~$ sudo smartctl -l selftest /dev/sda | grep -e "#"
# 1 Short offline Completed without error 00% 7264 -
# 2 Short offline Completed without error 00% 7240 -
# 3 Short offline Completed without error 00% 7219 -
# 4 Short offline Completed without error 00% 7192 -
# 5 Short offline Completed without error 00% 7168 -
# 6 Short offline Completed without error 00% 7144 -
# 7 Extended offline Completed without error 00% 7125 -
# 8 Short offline Completed without error 00% 7096 -
# 9 Short offline Completed without error 00% 7072 -
#10 Short offline Completed without error 00% 7049 -
#11 Short offline Completed without error 00% 7004 -
나는 Linux/bash를 처음 접했기 때문에 올바른 용어를 사용하고 있는지 잘 모르겠습니다.
어쨌든 저는 SMART 오류가 있는지 감지하고 알려주기 위해 Smartmontools를 사용하고 있습니다. 내가 원하는 방식으로 작동하지만 HDD에 대한 일일 통계를 얻고 싶었기 때문에 smartmontools 및 임시, SMART 값, 사용된 HDD 공간과 같은 기타 흥미로운 항목에서 정보를 수집하는 스크립트를 직접 만들었습니다. 아마도 이와 같은 일을 하는 가장 좋은 방법은 아닐 것입니다. 하지만 저는 이 일을 즐기며 계속해서 배우고 있습니다.
내가 보낸 이메일은 표를 만들고 긍정적/부정적 결과에 글꼴 색상(녹색/빨간색)을 추가하기 위해 HTML 형식으로 작성되었습니다. 그런데 자가 테스트를 표시하기 위한 테이블을 만들려고 하면 몇 가지 문제가 발생합니다.
내가 사용하는 명령은 다음과 같습니다. ( sudo smartctl -l selftest $HDD | grep '#' >> $SMARTFILE
루프에서 $HDD는 내 시스템의 모든 HDD이고 $SMARTFILE은 내가 저장하는 html 파일입니다.
이 명령의 출력은 다음과 같습니다.
#1 간략한 오프라인이 오류 없이 완료되었습니다. 00% 7264 -
#2 오류 없이 간략한 오프라인 완료 00% 7240 -
등. 다음 코드를 사용하여 드라이브의 일련 번호를 얻습니다.
HDDinfo="$(sudo smartctl --info $HDD | grep -e 'Serial Number')"
IFS=':' read -r -a array <<< "$HDDinfo"
sudo smartctl --info $HDD | grep -e 'Serial Number'
정상적으로 출력되기 때문에
일련 번호: WD-RESTOFS/N123
하지만 이를 테이블에 넣기 위해 ":" 문자를 사용하여 문자열을 구분하고 다음과 같은 배열을 얻었습니다.
일련 번호, WD-RESTOFS/N123
그러나 내가 얻고 있는 출력에는 sudo smartctl -l selftest $HDD | grep '#' >> $SMARTFILE
그것들을 분리할 확실한 방법이 없으며 이전에 했던 방식은 작동하지 않습니다. 왜냐하면 내가 원하는 문자열에 공백이 있어서 다음을 사용하여 분리할 수 없기 때문입니다. 공백 문자.
TL;DR, 다음 명령이 있고 sudo smartctl -l selftest /dev/sda | grep '#' >> $SMARTFILE
그 출력은 다음과 같습니다.
#1 간략한 오프라인이 오류 없이 완료되었습니다. 00% 7264 -
#2 오류 없이 간략한 오프라인 완료 00% 7240 -
다음과 같이 개별적으로 저장하기 위해 배열(또는 유사한 배열)을 만들고 싶습니다.
# 1, 일시적으로 오프라인, 오류 없이 완료됨, 00%, 7264, -
이렇게 하면 HTML 테이블에 쉽게 넣을 수 있습니다. 이것이 가능합니까? 오류가 발생하면 다음과 같이 나타날 수 있습니다.
#1 짧은 오프라인 완료: 읽기 실패 20% 717 555027747
불분명하거나 추가 정보가 필요한 경우 알려주시기 바랍니다.
답변1
위의 (작은) 메시지 샘플에서 smartctl
해당 부분은 본질적으로 "<space><소문자를 제외한 모든 것>"(줄 시작 부분의 "#nnn" 필드 제외)으로 구분된 것처럼 보입니다.
sed
부품을 분리하는 데 도움이 될 수 있습니다.
$ smartctl_output="\
# 1 Short offline Completed without error 00% 7264 -
# 2 Short offline Completed without error 00% 7240 -
# 1 Short offline Completed: read failure 20% 717 555027747"
$ csv="$( sed 's/ //; s/ \([^[:lower:]]\)/,\1/g' <<< "$smartctl_output" )"
$ echo "$csv"
#1,Short offline,Completed without error,00%,7264,-
#2,Short offline,Completed without error,00%,7240,-
#1,Short offline,Completed: read failure,20%,717,555027747
이것이 원하는 것이라면 이제 HDDinfo에서와 마찬가지로 어레이를 채울 수 있습니다.
[고쳐 쓰다]
sed
분할을 수행하는 부분에 대한 설명은 다음과 같습니다. sed
프로그램은 한 줄에 배치한 두 부분으로 구성됩니다. 확장 버전은 다음과 같습니다.
sed '
s/ //
s/ \([^[:lower:]]\)/,\1/g
'
프로그램은 sed
입력의 각 행에 대해 작동합니다. 즉, 행을 읽고 일련의 변환을 적용한 다음 해당 행을 인쇄합니다. 그런 다음 더 이상 읽을 줄이 없을 때까지 다음 줄부터 시작합니다.
여기서 첫 번째 sed
명령은 s/ //
"#"과 다음 숫자를 함께 넣기 위해 첫 번째 공백을 제거합니다.
그런 다음 두 번째 sed
명령은 s/ \([^[:lower:]]\)/,\1/g
각 필드의 시작 부분("<space><소문자를 제외한 모든 것>"으로 정의됨)을 검색하고 공백을 콜론으로 바꿉니다. 다음 필드의 첫 번째 문자를 나타내는 \1
대괄호 " " 사이의 정규식을 참조합니다 .\([^[:lower:]]\)
나머지 부분은 테스트입니다. sed
파일의 내용이나 명령의 출력을 입력하는 대신 변수 smartctl_output
(샘플로 구성된 문자열)를 입력하고 그 csv
변수에 결과를 할당합니다.
[업데이트#2]
이제 필드가 두 개 이상의 공백으로 구분된 것으로 보입니다. 이전보다 훨씬 쉬워졌습니다. 명령은 sed
다음과 같습니다.
sed 's/ \+/,/g'
즉, 두 개 이상의 공백으로 구성된 모든 계열을 콜론으로 바꿉니다.
답변2
쉘에서 로컬로 이 작업을 수행하는 방법이 생각나지 않지만 perl
예를 들어 다음을 정의할 수 있습니다.정규식필드 분할을 위해 이를 사용하여 원하는 단일 구분 기호를 삽입한 다음 IFS=,
다른 방법을 사용하여 간단히 읽을 수 있습니다.
귀하의 예에 따라 필드는 공백으로 구분되고 그 뒤에 다음이 올 수 있습니다.
- 대문자 또는 하이픈
- 적어도 두 개의 숫자로 구성된 시퀀스
그러니 명령을 파이프하세요.
. . . |
perl -F'[[:space:]](?=[[:upper:]-]|[[:digit:]]{2,})' -anle 'print join ",", @F'