파일의 각 줄의 특정 속성을 확인하십시오.

파일의 각 줄의 특정 속성을 확인하십시오.

나는 각각 공백(아마도 이중 공백)으로 구분된 31개의 숫자를 포함하는 100만 줄을 포함하는 여러 개(정확히 427개)의 텍스트 파일을 가지고 있습니다. 그러나 일부 데이터 손상이 있을 수 있으며, 가비지가 포함된 행이 있을 수 있습니다.

이제 각 행이 공백으로 구분된 31개 항목을 포함하는 속성을 만족하는지 확인하고 싶습니다. 항목이 숫자라고 가정합니다. 이를 확인하는 방법도 더 좋을 것입니다.

내 현재 방식은

while read line;
do
   if [ $(echo "$line" | sed 's/ /\n/g' | grep -v "^$" | wc -l) -ne 31 ]
   then
      echo "$file bad";
   fi
done < $file

이는 한 줄의 모든 공백을 개행 문자로 바꾸고, 빈 줄을 필터링하고, 줄 수를 계산하여 31과 비교합니다.

이 방법은 속도가 느리므로 멋진 정규식을 포함하는 더 나은 방법이 있을 수 있습니다. 더 빠른 방법은 무엇입니까?

답변1

grep한 사람만 안 되는 걸까요?

bash-4.2$ cat file
1 2 -3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32 33 -34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 L 51 52 53 54 55 56 57 58 59 60 61 62
63 64 -65 66 67 68 69
70 71 -72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

# listing bad lines in the file
bash-4.2$ grep -Exv '(-?[[:digit:]]+ +){30}-?[[:digit:]]+' file
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 L 51 52 53 54 55 56 57 58 59 60 61 62
63 64 65 66 67 68 69

# listing files with bad lines
bash-4.2$ grep -Exvl '(-?[[:digit:]]+ +){30}-?[[:digit:]]+' -- *
file

답변2

다음을 수행하세요.

awk 'NF != 31 || /[^0-9 -]/ {print FILENAME ":" FNR ": " $0}' file1 file2...

보고서에는 숫자가 아닌 값이 포함된 31개의 필드나 행이 포함되어 있지 않습니다. 호언장담 ---이나 예를 들지 않기 때문에 @manatwork의 솔루션만큼 엄격하지는 않지만 9-8아마도 더 효율적일 것입니다.

답변3

행을 배열로 읽어온 read -a다음 배열의 크기를 확인하는 데 사용할 수 있습니다. 이는 한 줄에 3개의 프로세스를 분기하는 하위 쉘을 생성하는 것보다 훨씬 낫습니다.

while read -ra line;
do
    if (( ${#line[@]} != 31 )); then
        echo "$file bad"
    fi
done < "$file"

관련 정보