Grep alias-파이프 라인에없는 경우 줄 번호


25

줄 번호를 추가하는 grep에 대한 bash 별칭을 만들고 싶습니다.

alias grep='grep -n'

그러나 물론 파이프 라인에도 라인 번호가 추가됩니다. 대부분의 경우 (그리고 예외는 생각 나지 않습니다.) 파이프 라인 내에서 줄 번호를 원하지 않습니다 (최소한 내부적으로, 마지막 경우 OK 일 것입니다). 그것들을 꺼내기위한 파이프 라인.

아마도 grep이 행에서 유일한 명령 인 경우 행 번호 만 추가하도록 요구 사항을 단순화 할 수 있습니다. 특히 추악한 별명 없이이 작업을 수행 할 수있는 방법이 있습니까?

답변:


27

bash (또는 POSIX 셸)에서 다음과 같은 함수를 사용할 수 있습니다.

grep() { 
    if [ -t 1 ] && [ -t 0 ]; then 
        command grep -n "$@"
    else 
        command grep "$@"
    fi
}

[ -t 1 ]일부는 사용 [명령 (로도 알려진 test) 표준 출력은 TTY와 연관되어 있는지 확인하기 위해.

[ -t 0 ]만 줄 번호를 추가 지정하기 때문에 검사 표준 입력은 물론, 경우 grep는 IS 에만 파이프 라인의 명령.


5
[[ -t 0 && -t 1 ]]표준 입력과 표준 출력이 모두 터미널에 연결되어 있으면 줄 번호 만 원하면 테스트 하십시오.
Gilles 'SO- 악마 그만

3

(완전성을 위해)

하지만 @의 enzotib의 대답은 대부분의 아마 당신이 원하는, 그것은 당신이 무엇을 요구하지 않습니다. [ -t 1 ]파일 디스크립터가 터미널 장치인지 확인합니다. 파이프 이외의 것이 아닙니다 (일반 파일, 소켓, 다른 유형의 장치와 같은 /dev/null...)

[명령에는 -t파이프에만 해당하는 것이 없습니다 . 파일 디스크립터와 연관된 파일 유형을 얻으려면 해당 파일에 대한 fstat()시스템 호출 을 수행해야 합니다. 이를위한 표준 명령은 없지만 일부 시스템이나 쉘에는 일부가 있습니다.

GNU로 stat:

grep() {
  if { [ "$(LC_ALL=C stat -c %F - <&3)" = fifo ]; } 3>&1 ||
     [ "$(LC_ALL=C stat -c %F -)" = fifo ]; then
    command grep "$@"
  else
    command grep -n "$@"
  fi
}

또는 zsh자체 stat내장 (GNU의 몇 년 전부터 존재)은 다음과 같이로드 zstat됩니다.

grep() {
  zmodload -F zsh/stat b:zstat
  local stdin_type stdout_type
  if zstat -A stdin_type -s -f 0 +mode &&
     zstat -A stdout_type -s -f 1 +mode &&
     [[ $stdin_type = p* || $stdout_type = p* ]]
  then
     command grep "$@"
  else
     command grep -n "$@"
  fi
}

이제 몇 가지 메모 :

파이프 를 사용하는 것은 셸 파이프 라인 만이 아닙니다 .

var=$(grep foo bar)

또는:

cmd <(grep foo bar)

또는:

coproc grep foo bar

또한 grepstdout이 파이프로 이동하여 실행 합니다.

쉘이 ksh93인 경우 일부 시스템에서는 파이프 라인의 파이프 대신 소켓 쌍을 사용합니다.

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