Grep alias-파이프 라인에없는 경우 줄 번호 추가됩니다. 대부분의 경우

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

alias grep='grep -n'

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

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



답변

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

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

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

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


답변

(완전성을 위해)

하지만 @의 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인 경우 일부 시스템에서는 파이프 라인의 파이프 대신 소켓 쌍을 사용합니다.