Aplique o comando “expand” em um arquivo no local, como sed -i

-1

O expandcomando não tem o equivalente a

sed -i <file>

expandna verdade tem uma -iopção - mas isso significa

somente após espaços em branco

Existe uma sed- expandcombinação dupla dinâmica para atingir o mesmo propósito?

javadba
fonte

Respostas:

0

O utilitário GNU expand não fornece a atualização 'in loco' que o sed fornece. É bastante trivial reproduzir o mesmo resultado, embora o comando possa ser mais lento por mais tempo.

Não é possível analisar e atualizar um arquivo simultaneamente em um sistema de arquivos arbitrário sem arriscar a corrupção, e por esse motivo e outros outros não o fazem, embora o abstraiam do usuário. O que o sed faz e você pode reproduzir é salvar a saída de sua operação no arquivo de objeto em um arquivo temporário, depois exclui a cópia original e renomeia a temp como original.

Existem várias maneiras de fazer isso, eis uma - o arquivo chamado orig.txt é o arquivo que está sendo 'expandido':

tmp=`mktemp` && expand orig.txt > "$tmp" && mv "$tmp" orig.txt

Se você nunca usar argumentos além do nome do arquivo para expandir, uma função simples chamada 'expand' poderá ocultar o arquivo temporário inteiro para a troca de arquivos original e reproduzir o comportamento 'sed' - essa implementação terá um único argumento do caminho / nome do arquivo

expand() {
  [[ "$#" -ne "1" ]] && { echo "A single argument must be provided"; exit 1; }
  tmp=`mktemp` && expand "$1" > "$tmp" && mv "$tmp" "$1"
}

Com uma pequena modificação, podemos recriar toda a funcionalidade de expansão suportando argumentos. Existe um pequeno truque para capturar o último argumento, para que possamos conhecer o nome do arquivo do objeto e, finalmente, substituí-lo pela saída de expand. O último argumento é referenciado como $ {@ -1}

expand() {
      [[ "$#" -lt "1" ]] && { echo "At least a file name argument must be provided"; exit 1; }
      # Here we capture the last argument which is the object file name
      fname="${@: -1}"
      # The upcoming call to expand passes on all arguments including the file name
      tmp=`mktemp` && expand "$@" > "$tmp" && mv "$tmp" "$fname"
    }

Como não testei esse código, peço desculpas se há um erro de sintaxe que não foi detectado.

Uma dessas funções, ou uma versão delas, deve ser colocada em .bashrc ou em um arquivo equivalente que é originado quando você cria um novo shell para que esteja prontamente disponível.

Se você deseja especificar se o arquivo é atualizado 'in place' ou se a atualização é enviada para o stdout, esse modelo de função pode ser modificado para fazer isso com base em um argumento adicional (que não é repassado para o stdout). expandir, mas muda como chamamos de expansão). Não tenho certeza se você está procurando isso, mas acho que você tem todas as informações necessárias para fazer isso agora, se estiver.

Ou, para mais diversão, faça o download do código-fonte GNU coreutils e do código-fonte sed , verifique como o sed lida com isso e migre esse código para sua nova versão aprimorada do expand. Envie essa alteração de volta aos mantenedores e você possivelmente simplificou isso para todos os futuros usuários de 'expansão'.

Argonautas
fonte
sim, eu fiz algo semelhante a isso .. apenas verificando se eu estava fazendo muito trabalho.
Javadba