"ed" 명령으로 어떤 파일이 변경되었는지 어떻게 확인할 수 있나요?

"ed" 명령으로 어떤 파일이 변경되었는지 어떻게 확인할 수 있나요?

모든 텍스트 파일이 개행 문자로 끝나는 것을 보장하는 스크립트를 작성하려고 합니다.

특정 폴더에서 이 명령을 실행하면 다음과 같습니다.

find . -exec ed -s {} <<< w \;

다음과 같은 결과가 나타납니다.

Newline appended
Newline appended
Newline appended
Newline appended
Newline appended
Newline appended
Newline appended
Newline appended
Newline appended
Newline appended
Newline appended

좋습니다. 하지만 어떤 파일에 개행 문자가 추가되나요? Git 기록에 변경 사항이 표시되지 않습니다. 추적되지 않은 파일도 마찬가지인가요?

또한 의도적으로 텍스트 파일 끝에서 개행 문자를 제거하고 ed다시 추가하지 않았습니다.

답변1

<<<입력 리디렉션(여기서는 문자열)이 find가 아닌 에 추가되었기 때문에 명령이 약간 잘못되었습니다 ed.

명령을 조금 확장하십시오.

find . -type f -exec sh -c '
    for pathname do
        echo w | ed -s "$pathname"
    done' sh {} +

이는 현재 디렉터리나 그 아래의 일반 파일에만 영향을 미치며 사용을 시도하지 않습니다 ed. 바이너리 파일도 일반 파일이므로 텍스트 파일이 포함된 디렉터리에서만 실행된다고 가정해야 합니다. 컴파일된 실행 파일, 이미지 파일 등을 손상시키지 않도록)

일반 파일 배치의 경우 짧은 인라인 쉘 스크립트가 호출됩니다. 스크립트는 주어진 경로 이름을 반복하여 에서 find각 경로를 연 다음 ed즉시 파일을 저장합니다. 이렇게 하면 아직 개행 문자로 끝나지 않은 파일에 개행 문자가 추가됩니다.

어떤 파일이 실제로 수정되었는지에 대한 힌트를 얻으려면 를 호출하기 전에 경로 이름을 인쇄하십시오 ed. 이것은 출력됩니다모두경로 이름을 찾았지만 목록의 일부 경로 뒤에는 "새 줄 추가" 메시지가 흩어져 있습니다.

find . -type f -exec sh -c '
    for pathname do
        printf "%s\n" "$pathname"
        echo w | ed -s "$pathname"
    done' sh {} +

실제로 수정된 파일을 검색하려면 임시 파일에 기록하여 원본 파일과 비교하고, 차이점이 있으면 원본 파일을 임시 파일로 바꾸면 됩니다.

find . -type f -exec sh -c '
    tmpfile=$(mktemp); trap "rm -f \"$tmpfile\"" EXIT
    for pathname do
        printf "w %s\n" "$tmpfile" | ed -s "$pathname" 2>/dev/null
        if ! cmp -s "$tmpfile" "$pathname"; then
            printf "Fixed %s\n" "$pathname"
            mv "$tmpfile" "$pathname"
        fi
    done' sh {} +

이 작업의 또 다른 이점은 실제로 수정된 파일 이외의 파일에 대한 타임스탬프를 업데이트하지 않는다는 것입니다.

이는 또한 "개행 추가" 메시지를 억제 ed하고 파일이 실제로 수정될 때 사용자 정의 메시지를 출력합니다.

또한보십시오:

관련 정보