나는 각각 공백(아마도 이중 공백)으로 구분된 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"