Como posso ver quais arquivos foram alterados pelo comando “ed”?

Como posso ver quais arquivos foram alterados pelo comando “ed”?

Estou tentando escrever um script que garanta que todos os arquivos de texto terminem com um caractere de nova linha.

Quando executo este comando em uma pasta específica:

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

Eu recebo a seguinte saída:

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

Ok, mas em quais arquivos as novas linhas foram anexadas? Não consigo ver nenhuma alteração no histórico do Git. Esses arquivos não são rastreados?

Também removi deliberadamente a nova linha do final de um dos meus arquivos de texto e ednão a adicionei novamente...

Responder1

Seu comando está um pouco errado, assim <<<como um redirecionamento de entrada (string aqui) anexado a find, não a ed.

Para expandir um pouco o seu comando:

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

Isso afetaria apenas arquivos regulares no diretório atual ou em qualquer lugar abaixo dele e não tentaria editar diretórios e outros tipos de arquivos com ed. Observe que os arquivos binários também são arquivos regulares, portanto devemos assumir que você só executa isso em diretórios contendo arquivos de texto (para não danificar executáveis ​​compilados, arquivos de imagem, etc.)

Para lotes de arquivos regulares, isso chamaria um pequeno script de shell em linha. O script percorreria os nomes de caminho fornecidos por finde abriria cada um deles ed, apenas para salvar imediatamente o arquivo. Isso adiciona a nova linha aos arquivos que ainda não terminam com um caractere de nova linha.

Para obter uma dica sobre quais arquivos são realmente modificados por isso, imprima o nome do caminho antes de chamar ed. Isso produziriatodosencontrou nomes de caminhos, mas a lista seria intercalada por mensagens de "Nova linha adicionada" após alguns deles.

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

Para detectar quais arquivos foram realmente modificados por isso, você pode gravar em um arquivo temporário, compará-lo com o arquivo original e substituir o original pelo arquivo temporário, se houver alguma diferença.

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 {} +

Isso tem o benefício adicional de que você não atualizará carimbos de data/hora em arquivos diferentes daqueles que você realmente modifica.

Isso também suprime a mensagem "Nova linha adicionada" ede, em vez disso, gera uma mensagem personalizada sempre que um arquivo for realmente modificado.

Veja também:

informação relacionada