Risposte:
Non puoi. Usa ed o GNU sed o perl, oppure fai quello che fanno dietro le quinte, ovvero creare un nuovo file per i contenuti.
ed, portatile:
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 nuovo file (consigliato, perché se lo script viene interrotto, puoi semplicemente eseguirlo di nuovo):
cut -d , -f 1,3 <foo >foo.new &&
mv -f foo.new foo
cut, sostituendo il file in atto (mantiene la proprietà e le autorizzazioni di foo, ma necessita di protezione contro le interruzioni):
cp -f foo foo.old &&
cut -d , -f 1,3 <foo.old >foo &&
rm foo.old
Consiglio di utilizzare uno dei cutmetodi basati su. In questo modo non dipendi da nessuno strumento non standard, puoi utilizzare lo strumento migliore per il lavoro e controllare il comportamento in caso di interruzione.
cut -d , -f 1,3 foo > foo.new rm foo mv foo.new foo
rm foo. E non dovresti chiamare rm foo, perché mv foo.new fooè atomico: rimuove la vecchia versione e mette in atto la nuova versione allo stesso tempo.
Il pacchetto moreutils di Ubuntu (e anche di Debian ) ha un programma chiamato sponge, che risolve anche il tuo problema.
Da uomo spugna:
sponge legge l'input standard e lo scrive nel file specificato. A differenza di un reindirizzamento della shell, la spugna assorbe tutto il suo input prima di aprire il file di output. Ciò consente di costringere pipeline che leggono e scrivono nello stesso file.
Che ti permetterebbe di fare qualcosa del genere:
cut -d <delim> -f <fields> somefile | sponge somefile
Non penso che sia possibile usare cutda soli. Non sono riuscito a trovarlo nella pagina man o info. Puoi fare qualcosa come
mytemp=$(mktemp) && cut -d" " -f1 file > $mytemp && mv $mytemp file
mktempti rende un file temporaneo relativamente sicuro in cui puoi convogliare l' cutoutput.
Puoi usare slurp con POSIX Awk:
cut -b1 file | awk 'BEGIN{RS="";getline<"-";print>ARGV[1]}' file
Bene, poiché cutproduce meno output di quello che legge, puoi fare:
cut -c1 < file 1<> file
Vale a dire, rendere il suo stdin fileaperto in modalità sola lettura e il suo stdout fileaperto in modalità lettura + scrittura senza troncamento ( <>).
In questo modo, cutsovrascriverà il file su se stesso. Tuttavia, il resto del file non verrà toccato. Ad esempio, se filecontiene:
foo
bar
L'output diventerà:
f
b
bar
L' f\nb\nhanno sostituito foo\n, ma barè ancora lì. Dovresti troncare il file al cuttermine.
Con ksh93, puoi farlo con il suo <>;operatore che agisce come <>se non fosse che se il comando ha successo, ftruncate()viene chiamato sul descrittore di file. Così:
cut -c1 < file 1<>; file
Con altre shell, avresti bisogno di farlo ftruncate()tramite altri mezzi come:
{ cut -c1 < file; perl -e 'truncate STDOUT, tell STDOUT';} 1<> file
anche se invocare perlsolo per questo è un po 'eccessivo qui soprattutto considerando che perlpuò facilmente fare quel cutlavoro come:
perl -pi -e '$_ = substr($_, 0, 1)' file
Fai attenzione che con tutti i metodi che prevedono l'effettiva riscrittura sul posto, se l'operazione viene interrotta a metà strada, finirai con un file danneggiato. L'uso di un secondo file temporaneo evita questo problema.
.oldmetodo per le modifiche sul posto,echo "$(cut -d , -f 1,3 <foo)" > foo