Aplique o comando "expandir" a um arquivo local como sed -i

Aplique o comando "expandir" a um arquivo local como sed -i

O expandcomando não tem o equivalente a

sed -i <file>

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

somente depois dos espaços em branco

Existe uma sedcombinação expandde dupla dinâmica para atingir o mesmo propósito?

Responder1

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 um pouco mais longo.

Não é possível analisar e atualizar um arquivo simultaneamente em um sistema de arquivos arbitrário sem correr o risco de corrupção e, por esse motivo e outros, o sed não faz isso, embora o abstraia do usuário. O que sed faz, e você mesmo pode reproduzi-lo, é salvar a saída de sua operação no arquivo objeto em um arquivo temporário, excluir a cópia original e renomear a temperatura como original.

Existem várias maneiras de fazer isso, aqui está 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 nenhum argumento além do nome do arquivo para expandir, uma função simples chamada expandpoderia ocultar todo o arquivo temporário para troca de arquivo original e reproduzir o sedcomportamento - esta implementação levaria um único argumento de 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 todas expandas funcionalidades apoiando argumentos. Há um pequeno truque para capturar o último argumento para que possamos saber o nome do arquivo objeto para que possamos sobrescrevê-lo com a 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"
    }

Não testei esse código, então peço desculpas se houver um erro de sintaxe que não detectei.

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

Se você quiser especificar se o arquivo será atualizado 'no local' ou se a atualização será enviada para stdout, este modelo de função pode ser modificado para fazer isso com base em um argumento adicional (que não é passado para expandir, mas muda a forma como chamamos de expandir). 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, baixe o GNU coreutilsCódigo fontee acódigo-fonte sed, veja 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'.

informação relacionada