Perl grep의 한 줄 버전을 별칭으로 바꾸는 방법은 무엇입니까?

Perl grep의 한 줄 버전을 별칭으로 바꾸는 방법은 무엇입니까?

나는 우리가 사용할 수 있다는 것을 발견했습니다

perl -wnle "/RE/ and print"

예를 들어

perl -wnle "/^.{0,80}$/ and print"

또는

grep -ri someText * | perl -wnle "/^.{0,80}$/ and print"

80자를 초과하는 줄을 제외합니다.

하지만 Bash에서 별칭으로 어떻게 설정합니까?

나는 시도했다:

alias pgrep='perl -wnle "/$1/ and print"'

그런 다음

grep -ri someText * | pgrep "^.{0,80}$"

하지만 그것은 말할 것이다

Can't open ^.{0,80}$: No such file or directory.

답변1

aliasbash아니요매개변수를 허용하도록 설계되었으며 매개변수가 제공되면 이를 어떻게 처리할지 알 수 없습니다. 일반적으로 피해야 하며 매우 간단한 명령 이름 대체에만 사용해야 합니다.

대신 기능을 사용하는 것이 좋습니다. 이는 pgrep유효한 Linux 바이너리이므로 사용해서는 안 됩니다. 명시적인 이름을 사용하는 것이 좋습니다.

perlgrep() {
    perl -wnle "/$1/ and print"
} 

이제 전화해

perlgrep '^.{0,80}$'

그런데 오류가 발생하는 이유는 alias매개변수 자체를 전달할 수 없기 때문에 확장이 발생하면 명령이 다음과 같이 되기 때문입니다.

grep -ri someText * | perl -wnle "/$1/ and print" '^.{0,80}$'

perl이는 '^.{0,80}$열려야 하고 정규식을 실행해야 하는 파일 이름으로 처리되기 때문에 잘못된 것입니다 .

답변2

참고하세요 pcregrep(~PCRE 라이브러리) 및 GNU grep -P(PCRE 지원으로 구축된 경우)는 Perl과 유사한 정규식을 사용하고 grep -PUTF-8 로케일에서 UTF-8 데이터를 정상적으로 처리할 수 있습니다.

이를 사용하려면 perl이를 수행하는 스크립트나 함수를 정의할 수 있습니다. 별칭은 별칭일 뿐이므로 한 문자열을 다른 문자열로 바꾸면 작동하지 않습니다.

다음을 수행할 수 있습니다.

perlgrep() (
  export RE="${1?}"; shift
  exec perl -Mopen=locale -Twnle '
    BEGIN {$ret = 1; $several_files = @ARGV > 1}
    if (/$ENV{RE}/) {
      $ret = 0;
      print $several_files ? "$ARGV: $_" : $_
    }
    END {exit $ret}' -- "$@"
)

하지만 조심해perl -n임의의 파일 이름에 대한 실행 효과위의 옵션은 이러한 문제를 부분적으로만 완화합니다 -T.

또한 를 사용하여 -Mopen=locale로캘의 문자 집합에 따라 입력을 디코딩하고 출력을 인코딩하지만 파일 이름 자체는 다음과 같습니다.코딩된하지만디코딩됨, 즉 파일 이름의 바이트 값이 127보다 크면 로케일의 문자 집합이 iso8859-1이 아니면 작동하지 않습니다.

마지막으로, 당신은 단지 필요합니다디코딩입력 라인 일치에만 사용됩니다. 다시 인코딩할 필요도 없고 파일 이름을 디코딩/인코딩할 필요도 없습니다.

따라서 최신 버전에서는 perl다음을 수행할 수 있습니다.

#! /usr/bin/perl --
use warnings;
use strict;
use Encode::Locale;
use Encode;

my $re = shift @ARGV;
my $several_files = @ARGV > 1;
my $ret = 1;

while (<<>>) {
  if (decode(locale => $_) =~ $re) {
    $ret = 0;
    print $several_files ? "$ARGV: $_" : $_
  }
}
exit $ret;

매개변수에서 임의 코드 삽입을 방지하기 위해 , (?{code})같은 정규식 연산자가 비활성화됩니다. 다시 원할 경우 (??{code})이 스크립트 상단에 추가할 수 있습니다.use re 'eval';

관련 정보