[unix] 줄의 시작 부분에 고정 줄 ​​잡기

grep "^$1"일종의 작품이지만 "$1"grep에서 어떻게 문자를 해석하지 못하도록 탈출 합니까?

아니면 더 좋은 방법이 있습니까?

편집 :
검색하고 싶지 '^$1'않지만 동적으로 삽입 된 고정 문자열은 줄의 시작 부분에있는 경우에만 일치해야합니다. 그것이 내가 의미하는 바입니다 $1.



답변

나는 이것을 사용하여 이것을 할 수있는 방법을 생각할 수 없다 grep. ^자체는 정규 표현식의 일부이므로이를 사용하려면 정규 표현식을 해석해야합니다. 그것은 하위 문자열 일치에 사용 사소한 awk, perl또는 무엇을 :

awk -v search="$1" 'substr($0, 1, length(search)) == search { print }'

을 포함하는 검색 문자열을 처리하려면 123의 답변\ 과 동일한 트릭을 사용할 수 있습니다 .

search="$1" awk 'substr($0, 1, length(ENVIRON["search"])) == ENVIRON["search"] { print }'


답변

일치하는 것이 있는지 여부 만 확인해야하는 경우 모든 입력 행을 원하는 접두사 길이 ( $1)로 자른 다음 고정 패턴 그렙을 사용하십시오.

if cut -c 1-"${#1}" | grep -qF "$1"; then
    echo "found"
else
    echo "not found"
fi

일치하는 줄의 수를 얻는 것도 쉽습니다.

cut -c 1-"${#1}" | grep -cF "$1"

또는 일치하는 모든 줄의 줄 번호 (줄 번호는 1부터 시작) :

cut -c 1-"${#1}" | grep -nF "$1" | cut -d : -f 1

줄 번호를 입력 head하고 tail일치하는 줄의 전체 텍스트를 얻을 수 있지만, 그 시점에서 Python 또는 Ruby와 같은 최신 스크립팅 언어를 사용하는 것이 더 쉽습니다.

위의 예는 Posix grep and cut을 가정합니다. 검색 할 파일이 표준 입력에서 온 것으로 가정하지만 대신 파일 이름을 사용하도록 쉽게 조정할 수 있습니다.

편집 : 또한 패턴 ( $1)이 길이가 0이 아닌 문자열 인지 확인해야 합니다. 그렇지 않으면 cut말을하지 values may not include zero. 또한 Bash를 사용하는 경우을 사용 set -o pipefail하여 오류 종료를 포착하십시오 cut.


답변

백 슬래시를 존중하는 펄을 사용하는 방법

v="$1" perl -ne 'print if index($_, $ENV{"v"} )==0' file

명령에 환경 변수 v를 설정 한 다음 변수의 색인이 0 인 경우 (예 : 행의 시작) 인쇄합니다.

awk에서도 동일하게 할 수 있습니다

v="$1" awk 'index($0, ENVIRON["v"])==1' file


답변

텍스트 처리에 bash를 권장하는 것이 아니라 all-bash 옵션이 있지만 작동합니다.

#!/usr/bin/env bash
# searches for $1 at the beginning of the line of its input

len=${#1}
while IFS= read -r line
do
  [[ "${line:0:len}" = "$1" ]] && printf "%s\n" "$line"
done

이 스크립트 len는 입력 된 매개 변수 $ 1 의 길이 를 계산 한 다음 각 줄에서 매개 변수 확장을 사용하여 첫 len문자가 $ 1과 일치 하는지 확인합니다 . 그렇다면 줄을 인쇄합니다.


답변

당신이 경우 $1순수 ASCII이고 당신이 grep있다 -P(PCRE를 사용하려면) 옵션을, 당신은이 작업을 수행 할 수 있습니다 :

#!/bin/bash

line_start="$1"
line_start_raw=$(printf '%s' "$line_start" | od -v -t x1 -An)
line_start_hex=$(printf '\\x%s' $line_start_raw)
grep -P "^$line_start_hex"

여기서 grep -P정규 표현식 \xXX을 사용하면 리터럴 문자를 지정할 수 있습니다 . 여기서 XX해당 문자의 16 진 ASCII 값이 있습니다. 특수 정규식 문자 인 경우에도 문자는 문자 그대로 일치합니다.

od는 예상 행 시작을 16 진 값 목록으로 변환하는 데 사용되며, 각 16 진수 값은 접두사로 묶고 \xprintf로 시작 합니다. ^그런 다음 필수 정규 표현식을 작성하기 위해이 문자열 앞에 붙습니다.


$1유니 코드 인 경우에 의해 출력 된 16 진수 바이트와 문자의 1 : 1 대응이 없기 때문에 이것은 조금 더 어려워집니다 od.


답변

필터로 :

perl -ne 'BEGIN {$pat = shift} print if /^\Q$pat/' search-pattern

하나 이상의 파일에서 실행하십시오.

perl -ne 'BEGIN {$pat = shift} print if /^\Q$pat/' search-pattern file..

perlre 문서“Quoting metacharacters”섹션에서 설명합니다 :

메타 문자 인용

펄에서 백 슬래쉬 메타 문자와 같은, 영숫자 \b, \w,
\n. 다른 정규 표현식 언어와 달리 영숫자가 아닌 백 슬래시 기호는 없습니다. 모습이 좋아하는 무엇이든 있도록 \\, \(, \), \[, \], \{, 또는 \}항상 리터럴 문자가 아닌 메타 문자로 해석됩니다. 이것은 한 번의 공용 관용구에서 패턴에 사용하려는 문자열에서 정규식 메타 문자의 특수 의미를 비활성화하거나 인용하는 데 사용되었습니다. “단어”이외의 문자를 모두 인용하십시오.

    $pattern =~ s/(\W)/\\$1/g;

( use locale설정된 경우 현재 로케일에 따라 다릅니다.) 오늘날에는
모든 메타 문자의 특수 의미를 비활성화 하기 위해 quotemeta함수 또는 \Q메타 인용 이스케이프 시퀀스를 사용하는 것이 일반적입니다 .

    /$unquoted\Q$quoted\E$unquoted/

\Q와 사이에 리터럴 백 슬래시 (보간 된 변수가 아닌 변수)를 \E넣으면 큰 따옴표 백 슬래시 보간으로 인해 결과가 혼동 될 수 있습니다. 에 리터럴 백 슬래시를 사용해야하는 경우 perlop의“따옴표 붙은 구문 구문 분석에 대한 기본 정보”를\Q...\E 참조하십시오 .

quotemeta그리고 \Q완전히 설명되어 있습니다 quotemeta .


답변

grep에 -P 옵션 ( PCRE 를 의미 함) 이있는 경우 다음을 수행 할 수 있습니다.

grep -P "^\Q$1\E"

질문을 참조하고 원하는 경우 PCRE 문서 를 참조하십시오 .