파일에서 줄 번호와 함께 특정 단어가 나오는 줄을 찾아서 줄 번호를 배열에 넣고 싶습니다. 배쉬에서는 어떻게 하나요?

파일에서 줄 번호와 함께 특정 단어가 나오는 줄을 찾아서 줄 번호를 배열에 넣고 싶습니다. 배쉬에서는 어떻게 하나요?

이것은 줄 번호를 반환하지만 문자열에 있습니다.

grep -n -F -w $word $file | cut -d : -f 1

답변1

나는 and awk대신 이것을 사용하겠습니다 . 행 번호를 배열에 넣으려면 다음을 사용하십시오.grepcut프로세스 교체및 bash 내장( mapfilein bash 의 동의어는 bash 에서 실행하면 bash보다 더 좋고 자세한 도움말을 얻을 수 있습니다). 예를 들어:mapfilereadarrayhelp mapfilehelp readarray

mapfile -t array < <(awk -v w="$word" '$0 ~ w {print NR}' "$file")

또는 정규식 일치 대신 고정 문자열 일치를 사용하십시오.

mapfile -t array < <(awk -v w="$word" 'index($0,w) {print NR}' "$file")

둘 다 $wordawk의 옵션을 통해 awk 변수에 쉘 변수를 전달하므로 포함된 문자열은 무엇이든 안전합니다. 큰따옴표로 묶인 awk 스크립트에서 $word를 사용하는 것보다 훨씬 안전합니다.w-v

FNR참고: 입력 파일이 여러 개인 경우 대신 인쇄할 수 있습니다 NR. NR은 지금까지 읽은 모든 행의 누적 합계입니다. FNR은 라인 번호입니다.현재 파일오직. (내가 "행"이라고 말할 때 실제로는 "레코드"를 의미합니다. 왜냐하면 awk는 개행으로 구분된 레코드가 있는 일반 텍스트 파일 이상의 것을 처리할 수 있기 때문입니다.)

답변2

bash행의 내용을 배열로 읽으 려면 다음을 사용할 수 있습니다 readarray -t.mapfile매핑그리고 아니문서zsh/mapfile이로 인해 모듈 zsh및 해당 $mapfile특수 연관 배열(실제 맵 파일) 과 혼동이 발생합니다 .

readarray -t array < <(
  grep -nFwe "$word" -- "$file" | cut -d : -f 1
)

--(그런데, 그 주위에 및/또는 따옴표를 확장하는 것을 잊었습니다 -e.)

또는 Split+glob 연산자를 사용할 수 있으며, 모두 숫자이므로 glob 비활성화를 건너뛸 수 있습니다.

IFS=$'\n'
array=( $(grep -nFwe "$word" -- "$file" | cut -d : -f 1) )

이것의 장점은 파이프의 종료 상태가 보존된다는 것입니다.

zsh에서는 매개변수 확장 플래그를 사용하여 수정 없이 f온라인 eed를 분할 할 수 있습니다 .f$IFS

array=( ${(f)"$(grep -nFwe "$word" -- "$file" | cut -d : -f 1)" } )

그러나 여기에서는 기본값을 사용할 수도 있습니다( zsh에서는 이를 변경할 $IFS이유가 없습니다 ).$IFS

array=( $(grep -nFwe "$word" -- "$file" | cut -d : -f 1) )

관련 정보