Respuestas:
No puedes Utilice ed o GNU sed o perl, o haga lo que hacen detrás de escena, que es crear un nuevo archivo para el contenido.
ed, portátil:
ed foo <<EOF
1,$s/^\([^,]*\),\([^,]*\),\([^,]*\).*/\1,\3/
w
q
EOF
GNU sed:
sed -i -e 's/^\([^,]*\),\([^,]*\),\([^,]*\).*/\1,\3/' foo
Perl:
perl -i -l -F, -pae 'print @F[1,3]' foo
cut, creando un nuevo archivo (recomendado, porque si su secuencia de comandos se interrumpe, puede ejecutarla nuevamente):
cut -d , -f 1,3 <foo >foo.new &&
mv -f foo.new foo
cut, reemplazando el archivo en su lugar (conserva la propiedad y los permisos de foo, pero necesita protección contra interrupciones):
cp -f foo foo.old &&
cut -d , -f 1,3 <foo.old >foo &&
rm foo.old
Recomiendo usar uno de los cutmétodos basados. De esa manera, no depende de ninguna herramienta no estándar, puede usar la mejor herramienta para el trabajo y controlar el comportamiento en la interrupción.
cut -d , -f 1,3 foo > foo.new rm foo mv foo.new foo
rm foo. Y no debe llamar rm foo, porque mv foo.new fooes atómico: elimina la versión anterior y coloca la nueva versión al mismo tiempo.
El paquete moreutils de ubuntu (y también debian ) tiene un programa llamado sponge, que también resuelve su problema.
De hombre esponja:
la esponja lee la entrada estándar y la escribe en el archivo especificado. A diferencia de una redirección de shell, la esponja absorbe toda su entrada antes de abrir el archivo de salida. Esto permite restringir las tuberías que leen y escriben en el mismo archivo.
Lo que te permitiría hacer algo como:
cut -d <delim> -f <fields> somefile | sponge somefile
No creo que sea posible usar cutsolo. No pude encontrarlo en el hombre o en la página de información. Puedes hacer algo como
mytemp=$(mktemp) && cut -d" " -f1 file > $mytemp && mv $mytemp file
mktemplo convierte en un archivo temporal relativamente seguro en el que puede canalizar la cutsalida.
Puede usar slurp con POSIX Awk:
cut -b1 file | awk 'BEGIN{RS="";getline<"-";print>ARGV[1]}' file
Bueno, dado que cutproduce menos salida de lo que lee, puede hacer:
cut -c1 < file 1<> file
Es decir, haga que su entrada estándar sea fileabierta en modo de solo lectura y que sea fileabierta en modo lectura + escritura sin truncamiento ( <>).
De esa manera, cutsimplemente sobrescribirá el archivo sobre sí mismo. Sin embargo, dejará el resto del archivo intacto. Por ejemplo, si filecontiene:
foo
bar
La salida se convertirá en:
f
b
bar
La f\nb\nhan reemplazado foo\n, pero bartodavía está allí. Debería truncar el archivo una vez que cuthaya finalizado.
Con ksh93, puede hacerlo con su <>;operador, que actúa como, <>excepto que si el comando tiene éxito, ftruncate()se llama en el descriptor de archivo. Entonces:
cut -c1 < file 1<>; file
Con otros proyectiles, deberías hacerlo a ftruncate()través de otros medios como:
{ cut -c1 < file; perl -e 'truncate STDOUT, tell STDOUT';} 1<> file
aunque invocar perlsolo por eso es un poco exagerado, especialmente teniendo en cuenta que perlpuede hacer fácilmente ese cuttrabajo como:
perl -pi -e '$_ = substr($_, 0, 1)' file
Tenga en cuenta que con todos los métodos que implican una reescritura real en el lugar, si la operación se interrumpe a mitad de camino, terminará con un archivo dañado. El uso de un segundo archivo temporal evita este problema.
.oldmétodo para los cambios en el lugar,echo "$(cut -d , -f 1,3 <foo)" > foo