sed에 정규 표현식이 포함된 경우 파일을 건너뛰는 방법은 무엇입니까?

sed에 정규 표현식이 포함된 경우 파일을 건너뛰는 방법은 무엇입니까?

현재 다음을 사용하고 있습니다단순화된 명령도착하다후행 공백 제거그리고파일 끝에 개행 문자 추가필요한 경우:

find . -type f -exec sed -i -e 's/[ \t]\+\(\r\?\)$/\1/;$a\' {} \+

곧 알게 되겠지만 여기에는 두 가지 문제가 있습니다.바이너리 파일파일 끝에 개행 문자를 추가합니다.␍␊ 줄 구분 기호. 커밋 또는 이와 유사한 경우 이러한 수정 사항은 쉽게 실행 취소되거나 건너뛰지 git gui만 복구 양을 최소화하고 싶습니다. 이를 위해:

스킵하는 방법이 있나요모두다음과 같은 경우 파일을 제출하세요.어느행은 sed?의 정규식과 일치합니다.

* ␀ 문자가 없는 바이너리가 있을 수 있고, 의도적으로 개행이나 ␀ 문자를 혼합한 파일이 있을 수 있다는 것을 알고 있습니다. 하지만 저는 사람의 개입을 최소화하는 솔루션을 찾고 있습니다. 나할 수 있다작업하려는 모든 파일 확장자를 나열하는 것이 가능하지만 이는 지속적으로 확인해야 하는 매우 긴 목록이 되며 이름 충돌로 인해 바이너리가 빠져나갈 가능성이 여전히 있습니다.

복잡한해결책:

while IFS= read -r -d '' -u 9
do
    if [[ "$(file -bs --mime-type -- "$REPLY")" = text/* ]]
    then
        sed -i -e 's/[ \t]\+\(\r\?\)$/\1/;$a\' -- "$REPLY"
    else
        echo "Skipping $REPLY" >&2
    fi
done 9< <(find . -type f -print0)

답변1

git바이너리 파일이 무엇인지에 대한 아이디어를 믿는다면 git grep. t.cpp텍스트 파일과 ls바이너리 파일이 모두 체크인되었다고 가정 합니다.

$ ls
t.cpp ls
$ git grep -I --name-only -e ''
t.cpp

-I옵션의 의미는 다음과 같습니다.

-I
바이너리 파일의 패턴과 일치하지 않습니다.

이것을 표현식과 결합하십시오 sed.

$ git grep -I --name-only -z -e '' | \
       xargs -0 sed -i.bk -e 's/[ \t]\+\(\r\?\)$/\1/;$a\'

( -z/ xargs -0이상한 파일 이름을 처리하는 데 도움이 됩니다.)

git grep다른 유용한 옵션에 대해서는 매뉴얼 페이지를 확인하십시오 . --no-index또는 --cached작업하려는 파일 세트에 따라 도움이 될 수도 있습니다.

답변2

sed의 정규식과 일치하는 줄이 있으면 전체 파일을 건너뛸 수 있는 방법이 있습니까?

바로 여기에.

# test case for skipping file if a sed regex match succeeds

echo 'Hello, world!' > hello_world.txt
cat hello_world.txt
ls -li hello_world.txt

sed -i -e '/.*Hello.*/{q;}; s/world/WORLD/g' hello_world.txt # skips file
sed -i -e '/.*HeLLo.*/{q;}; s/world/WORLD/g' hello_world.txt

답변3

다음은 인수(파일 이름이어야 함)를 반복하고 개행으로 끝나지 않는 각 파일에 개행을 추가하는 Perl 스크립트입니다. null 바이트가 포함된 파일은 건너뜁니다. 이미 개행 문자로 끝나는 파일은 수정되지 않습니다. CR이 포함된 파일에는 CRLF가 추가되고 다른 파일에는 LF만 추가됩니다. 검증되지 않은.

#!/usr/bin/env perl
foreach my $f (@ARGV) {
    open F, "<", $f or die;
    my $last = undef;
    my $cr = 0;
    while (<>) {if (/\0/) {undef $last; break} $last = $_; ++$cr if /\r$/}
    close F;
    if (defined $last && $last !~ /\n\Z/) {
        open F, ">>", $f or die;
        print($cr ? "\r\n" : "\n");
        close F or die;
    }
}

관련 정보