"test_result.txt" 파일에 특정 줄을 추가하기 위해 많은 양의 파일을 처리하려고 합니다. 다음 코드를 사용하여 달성했습니다. 그다지 우아하지는 않습니다.
for i in *merged; do
while read -r lo; do
if [[ $lo == *"ID"* ]]; then
echo $lo >> test_result.txt
fi
if [[ $lo == *"Instance"* ]]; then
echo $lo >> test_result.txt
fi
if [[ $lo == *"NOT"* ]]; then
echo $lo >> test_result.txt
fi
if [[ $lo == *"AI"* ]]; then
echo $lo >> test_result.txt
fi
if [[ $lo == *"Sitting"* ]]; then
echo $lo >> test_result.txt
done < $i
done
그러나 크기를 줄이기 위해 배열을 사용해 보았으나 다소 실패했습니다.
KEYWORDS=("ID" "Instance" "NOT" "AI" "Sitting" )
KEY_COUNT=0
for i in *merged; do
while read -r lo; do
if [[$lo == ${KEYWORDS[@]} ]]; then
echo $lo >> ~/Desktop/test_result.txt && KEY_COUNT="`expr $KEY_COUNT + 1`"
fi
done < $i
done
답변1
단어 집합 중 적어도 하나를 포함하는 파일 집합에서 모든 줄을 가져오려는 것 같습니다.
당신이하지 않는다고 가정수천파일에서 grep
단일 명령으로 이 작업을 수행할 수 있습니다.
grep -wE '(ID|Instance|NOT|AI|Sitting)' ./*merged >outputfile
그러면 패턴에 나열된 단어와 일치하는 이름이 일치하는 파일에서 행이 추출됩니다 *merged
.
with는 주어진 -w
문자열이 grep
하위 문자열과 일치하지 않는지 확인합니다(즉, NOT
내에서 일치하지 않음 NOTICE
). 이 옵션을 사용하면 -E
패턴을 변경할 수 있습니다.|
-h
일치하는 줄의 파일 이름을 출력에 포함하지 않으려면 이 옵션을 명령에 추가하세요.
수천 개의 파일이 있는 경우 명령줄이 너무 길어서 위 명령이 실패할 수 있습니다. 이 경우 다음과 같은 작업을 수행할 수 있습니다.
for file in ./*merged; do
grep -wE '(ID|Instance|NOT|AI|Sitting)' "$file"
done >outputfile
grep
파일당 한 번씩 명령이 실행됩니다.
find . -maxdepth 1 -type f -name '*merged' \
-exec grep -wE '(ID|Instance|NOT|AI|Sitting)' {} + >outputfile
grep
이렇게 하면 한 번에 최대한 많은 파일을 호출할 수 있는 횟수가 줄어듭니다.
관련된:
답변2
배열을 추가하는 것은 특별히 도움이 되지 않습니다. 여전히 배열의 요소를 반복해야 합니다(참조:항목이 bash 배열에 있는지 테스트하는 방법은 무엇입니까?):
while read -r lo; do
for keyword in "${keywords[@]}"; do
if [[ $lo == *$keyword* ]]; then
echo $lo >> ~/Desktop/test_result.txt && KEY_COUNT="`expr $KEY_COUNT + 1`"
fi
done
done < "$i"
다음 명령문을 사용하는 것이 더 나을 수도 있습니다 case
.
while read -r lo; do
case $lo in
*(ID|Instance|NOT|AI|Sitting)*)
echo "$lo" >> ~/Desktop/test_result.txt && KEY_COUNT="`expr $KEY_COUNT + 1`"
;;
esac
done < "$i"
(루프에서 이 라인을 추가로 처리한다고 가정합니다. 그렇지 않은 경우 grep 또는 awk가 이 작업을 더 효율적으로 수행할 수 있습니다.)