
El expand
comando no tiene el equivalente de
sed -i <file>
expand
en realidad tiene una -i
opción, pero significa
solo después de los espacios en blanco
sed
¿ Existe una expand
combinación de dúo dinámico para lograr el mismo propósito?
Respuesta1
La utilidad GNU expand no proporciona la actualización "in situ" que ofrece sed. Es bastante trivial reproducir el mismo resultado, aunque el comando puede ser un poco más largo.
No es posible analizar y actualizar un archivo simultáneamente en un sistema de archivos arbitrario sin correr el riesgo de dañarlo, y por esa y otras razones sed realmente no lo hace, aunque lo abstrae del usuario. Lo que hace sed, y puede reproducirlo usted mismo, es guardar el resultado de su operación en el archivo objeto en un archivo temporal, luego elimina la copia original y cambia el nombre del archivo temporal al original.
Hay varias formas de hacer esto, aquí hay una: el archivo llamado orig.txt es el archivo que se está 'expandiendo':
tmp=`mktemp` && expand orig.txt > "$tmp" && mv "$tmp" orig.txt
Si nunca usa ningún argumento más allá del nombre del archivo para expandir, una función simple llamada expand
podría ocultar todo el archivo temporal para el intercambio del archivo original y reproducir el sed
comportamiento; esta implementación tomaría un solo argumento de ruta/nombre de archivo.
expand() {
[[ "$#" -ne "1" ]] && { echo "A single argument must be provided"; exit 1; }
tmp=`mktemp` && expand "$1" > "$tmp" && mv "$tmp" "$1"
}
Con una pequeña modificación podemos recrear toda expand
la funcionalidad apoyando argumentos. Hay un pequeño truco al tomar el último argumento para que sepamos el nombre del archivo objeto y finalmente podamos sobrescribirlo con la salida de expand
. Se hace referencia al último argumento 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"
}
No probé este código, así que me disculpo si hay un error de sintaxis que no detecté.
Una de estas funciones, o una versión de ellas, debe colocarse en .bashrc
un archivo equivalente que se obtiene al crear un nuevo shell para que esté fácilmente disponible.
Si desea poder especificar si el archivo se actualiza "en el lugar" o no o si la actualización se envía a la salida estándar, esta plantilla de función podría modificarse para hacerlo en función de un argumento adicional (que no se pasa a expandir, pero cambia la forma en que llamamos expandir). No estoy seguro de si estás buscando eso, pero creo que tienes toda la información que necesitas para hacerlo ahora si es así.
O para más diversión, descargue GNU coreutilscódigo fuentey elcódigo fuente sed, compruebe cómo lo maneja sed y migre ese código a su nueva versión mejorada de expand. Envíe ese cambio a los mantenedores y posiblemente lo haya simplificado para todos los futuros usuarios "expandidos".