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