리터럴 탭을 사용하지 않고 탭을 grep하는 방법과 왜 작동하지 않습니까?


146

(e) grep을 사용하여 파일에서 탭을 검색 할 때는 리터럴 탭 ( ^v + <tab>)을 사용합니다 . \t정규식에서 탭을 대신 할 수는 없습니다 . 예를 들어 sed를 사용하면이 표현이 잘 작동합니다.

따라서 비 리터럴 대체품을 사용할 가능성이 있습니까? 그리고 <tab>작동하지 않거나 해석되지 않은 배경은 무엇 \t입니까?


답변:


206

grep은 POSIX 에서 정의한 정규식을 사용하고 있습니다. 어떤 이유로 POSIX가 \t탭으로 정의되지 않았습니다 .

몇 가지 대안이 있습니다.

  • grep에게 perl에 의해 정의 된 정규식을 사용하도록 지시하십시오 (perl에는 \t탭이 있음).

    grep -P "\t" foo.txt

    매뉴얼 페이지는 이것이 "실험적인"기능이라고 경고합니다. 적어도 \t잘 작동하는 것 같습니다. 그러나 고급 펄 정규식 기능은 그렇지 않을 수 있습니다.

  • printf를 사용하여 탭 문자를 인쇄하십시오.

    grep "$(printf '\t')" foo.txt
  • 리터럴 탭 문자를 사용하십시오.

    grep "^V<tab>" foo.txt

    즉 : 유형 grep ", 다음 Enter 키를 눌러 ctrl+v다음 Enter 키를 눌러, tab다음 입력 " foo.txt. ctrl+v터미널에서를 누르면 다음 키가 그대로 사용됩니다. 이는 터미널이 탭 키에 바인딩 된 일부 기능을 트리거하는 대신 탭 문자를 삽입 함을 의미합니다.

  • bash 의 주석 인용 기능을 사용하십시오 .

    grep $'\t' foo.txt

    모든 쉘에서 작동하지는 않습니다.

  • awk를 사용하십시오 :

    awk '/\t/'
  • sed를 사용하십시오 :

    sed -n '/\t/p'

POSIX 및 기타 시스템에서 정의 된 문자 클래스에 대한 개요는 정규식에 대한 Wikipedia 기사를 참조하십시오 .


: enzotib의 답변을 근거로 나를는 다음을 추가 할 수 있습니다 grep $'\t' foo.txt(하지만 일반적으로 쓰는 것 fgrep대신를 grep)
월터 Tross에게

환경 변수 값을 사용하여 이것을 필요로했습니다. 나는 사용했다 grep "$(printf '\t')${myvar}" foo.txt. 잘 작동했습니다. 몇 번의 시도만으로도 마지막 양식을 사용할 수 없었습니다.
sancho.s

1
일반 grep\t탭으로 자동 해석하지 못하는 이유가 있습니까? POSIX가 \t다른 의미를 요구합니까 ? 아마도 리터럴과 일치 \ 하고 t?
Aaron McDaid

BSD (OSX 포함) grep에 -P 옵션이 없다는 점에 유의하십시오.
TextGeek

매뉴얼 페이지에서 This is highly experimental and grep -P may warn of unimplemented features.아마도 -P레거시 시스템에서 사용하는 것은 좋지 않습니다 . printf선택은 더
Avindra Goolcharan

13

정확하게 듣고 싶은 답은 아니지만 bash는 이스케이프 시퀀스를 사용할 수 있습니다.

command | grep $'\t'

(큰 따옴표로 묶지 마십시오!).


1
-E가 필요하지 않습니다 (검색되는 것은 정규식 없음). 또한 명령에서 파이프 할 필요가 없습니다. bash의 매우 간과 된 기능 (작은 따옴표로 묶은 문자열 앞에 $가 있음)을 지적 해 주셔서 감사합니다.
Walter Tross

2
실제로, @enzotib은 대답을 간단히 편집하는 것이 좋습니다 grep $'\t'.
Teemu Leisti 2016 년

이것은 bash의 기능이며 다른 쉘 (예 : Ubuntu 및 기타 쉘 스크립트의 기본값 인 대시)과 같은 다른 쉘에서 실행될 경우 잘못된 작업을 수행한다는 사실을 강조해야합니다.
xjcl


1

탭에는 항상 ASCII 16 진수 코드를 사용하는 것이 좋습니다.

$ echo "one"$'\t'"two" > input.txt                                 

$ grep -P "\x9" input.txt                                          
one two

$ grep $'\x9' input.txt                                            
one two
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.