나는 우리가 사용할 수 있다는 것을 발견했습니다
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
alias
bash
예아니요매개변수를 허용하도록 설계되었으며 매개변수가 제공되면 이를 어떻게 처리할지 알 수 없습니다. 일반적으로 피해야 하며 매우 간단한 명령 이름 대체에만 사용해야 합니다.
대신 기능을 사용하는 것이 좋습니다. 이는 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 -P
UTF-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';