Bash 스크립트에서 텍스트가 처음 나타나는 줄 번호 찾기

Bash 스크립트에서 텍스트가 처음 나타나는 줄 번호 찾기

텍스트 파일의 줄 시작 부분에 있어야 하는 특정 검색 문자열이 처음 나타나는 줄 번호를 찾아 내 bash 스크립트의 변수에 저장해야 합니다. 예를 들어 "c"가 처음 나타나는 것을 찾고 싶습니다.

abc
bde
cddefefef // this is the line that I need its line number
Casdasd // C here is capital, I dont need it
azczxczxc
b223r23r2fe
Cssdfsdfsdf
dccccdcdcCCDcdccCCC
eCCCCCC

이걸 생각해냈는데 보시다시피 문제가 크네요

   trimLineNum=$(cat "${varFileLog}" | grep -m1 -n "c")
   echo "c is at line #"${trimLineNum}

출력은 다음과 같습니다:

c is at line #1:abc

질문:

  1. 해당 줄에 "c"가 있기 때문에 분명히 첫 번째 줄과 일치합니다.
  2. 출력에는 해당 줄의 내용도 포함됩니다! 나는 그것이 단지 줄 번호이길 원한다.

이러한 문제를 해결하려면 무엇을 변경해야 합니까?

답변1

POSIX를 사용하면 sed일반 출력을 억제하는 옵션을 사용할 수 있으며 -n(pattern)으로 시작하는 줄의 경우 및 uit를 사용하여 줄 번호를 인쇄할 수 있습니다.c^c=q

sed -n '/^c/{=;q;}'

GNU를 사용하면 명령을 sed사용하여 출력 없이 종료하고 다음으로 단순화할 수 있습니다 .Q

sed '/^c/!d;=;Q'

답변2

여러 솔루션이 존재합니다

awk와 함께

awk '/^c/ { print NR; exit}' "${varFileLog}"
  • /^c/: 다음으로 시작하는 줄과 일치합니다.c
  • print NR: 레코드(라인) 번호 인쇄
  • exit: 처리를 계속하지 않습니다

예상대로 awk이것이 내가 선호하는 솔루션입니다.

grep + 필터 사용

grep -n '^c' "${varFileLog}" | head -n1 | sed 's/:.*//'
  • '^c': 다음으로 시작하는 줄과 일치합니다.c
  • head -1: grep 결과의 첫 번째 줄만 표시
  • sed 's/:.*//': 이후에 무엇이든 삭제:

sed 's/:.*//'이 경우에도 cut -d: -f1같은 효과 가 있습니다

성능 정보

Stephen의 솔루션보다 느릴 수 있습니다.

grep -m1 -n '^c' "${varFileLog}" | cut -d: -f1

답변3

grep일치 항목을 줄의 시작 부분에 고정하여 "줄의 시작 부분에 있어야 함" 제약 조건을 고려해야 합니다 ^.

trimLineNum=$(grep -m1 -n -- '^c' "${varFileLog}")

그런 다음 사후 프로세스의 출력에는 grep줄 번호만 유지됩니다.

trimLineNum=$(grep -m1 -n -- '^c' "${varFileLog}")
trimLineNum="${trimLineNum%%:*}"

이것은 -mGNU 확장입니다(GNU의 경우 GNU는 옵션이 아닌 인수 이후에도 옵션을 허용하므로 짝수 로 시작할 grep필요가 없습니다 ) . 표준적으로 출력을 .--^c--$varFileLog-grephead -n 1

일치하는 항목이 없으면 첫 번째 명령은 false/fail을 반환하고, 두 번째 명령은 pipefail여러 셸( bash.

답변4

사용행복하다(이전 Perl_6)

raku -ne 'state $i; ++$i; say "c starts line $i" and last if m/^c/;'  

또는

raku -ne 'state $i; ++$i; say "c starts line $i" and last if (.index("c").defined && .index("c") == 0);' 

또는

raku -ne 'state $i; ++$i; say "c starts line $i" and last if .starts-with("c");' 

산출:

c starts line 3

-neRaku(라인별 비자동 인쇄) 명령줄 플래그를 사용하세요. 줄 번호를 얻으려면 state변수를 $i한 번 초기화한 다음 줄을 읽을 때마다 증가합니다. "c" 줄의 시작 부분이 식별되면(정규식 또는 , index또는 을 통해 starts-with) 문자열이 "c starts line $i"보간되어 출력됩니다( say).

as last참고: 위의 각 예에는 낮은 우선순위 조건이 추가되었습니다. 일치하는 모든 줄 번호를 반환하려면 이 조건을 제거하세요. 예:

~$ raku -ne 'state $i; ++$i; say "c starts line $i" if m/^c/;'  file
c starts line 3
c starts line 10

부록: 감사합니다이 답변, Raku 루틴을 사용하여 "c"로 시작하는 0 인덱스의 첫 번째 줄 번호를 얻는 빠른 방법은 다음과 같습니다 first.

~$ raku -e 'say lines.first(* ~~ / ^ c /):k;' file
2

#OR

~$ perl6 -e 'say lines.first(*.starts-with("c")):k;'  file
2

입력 예:

abc
bde
cddefefef // this is the line that I need its line number
Casdasd // C here is capital, I dont need it
azczxczxc
b223r23r2fe
Cssdfsdfsdf
dccccdcdcCCDcdccCCC
eCCCCCC
cddefefef // this is the line that I need its line number (again)

https://raku.org

관련 정보