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 cut
metodi 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 cut
da 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
mktemp
ti rende un file temporaneo relativamente sicuro in cui puoi convogliare l' cut
output.
Puoi usare slurp con POSIX Awk:
cut -b1 file | awk 'BEGIN{RS="";getline<"-";print>ARGV[1]}' file
Bene, poiché cut
produce meno output di quello che legge, puoi fare:
cut -c1 < file 1<> file
Vale a dire, rendere il suo stdin file
aperto in modalità sola lettura e il suo stdout file
aperto in modalità lettura + scrittura senza troncamento ( <>
).
In questo modo, cut
sovrascriverà il file su se stesso. Tuttavia, il resto del file non verrà toccato. Ad esempio, se file
contiene:
foo
bar
L'output diventerà:
f
b
bar
L' f\nb\n
hanno sostituito foo\n
, ma bar
è ancora lì. Dovresti troncare il file al cut
termine.
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 perl
solo per questo è un po 'eccessivo qui soprattutto considerando che perl
può facilmente fare quel cut
lavoro 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.
.old
metodo per le modifiche sul posto,echo "$(cut -d , -f 1,3 <foo)" > foo