Respostas:
Você não pode. Use ed ou GNU sed ou perl, ou faça o que eles fazem nos bastidores, que é criar um novo arquivo para o conteúdo.
edportá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, criando um novo arquivo (recomendado, porque se o seu script for interrompido, você poderá executá-lo novamente):
cut -d , -f 1,3 <foo >foo.new &&
mv -f foo.new foo
cut, substituindo o arquivo no lugar (mantém a propriedade e as permissões de foo, mas precisa de proteção contra interrupções):
cp -f foo foo.old &&
cut -d , -f 1,3 <foo.old >foo &&
rm foo.old
Eu recomendo usar um dos cutmétodos baseados em. Dessa forma, você não depende de nenhuma ferramenta não padrão, pode usar a melhor ferramenta para o trabalho e controlar o comportamento em interrupção.
cut -d , -f 1,3 foo > foo.new rm foo mv foo.new foo
rm foo. E você não deve ligar rm foo, porque mv foo.new fooé atômico: remove a versão antiga e coloca a nova versão ao mesmo tempo.
O pacote moreutils do ubuntu (e também do debian ) tem um programa chamado sponge, que também resolve o seu problema.
Da esponja do homem:
esponja lê a entrada padrão e a grava no arquivo especificado. Ao contrário de um redirecionamento de shell, a esponja absorve toda a sua entrada antes de abrir o arquivo de saída. Isso permite que os pipelines restritos sejam lidos e gravados no mesmo arquivo.
O que permitiria fazer algo como:
cut -d <delim> -f <fields> somefile | sponge somefile
Eu não acho que isso é possível usando cutsozinho. Não consegui encontrá-lo na página de informações ou homem. Você pode fazer algo como
mytemp=$(mktemp) && cut -d" " -f1 file > $mytemp && mv $mytemp file
mktempfaz de você um arquivo temporário relativamente seguro no qual você pode canalizar a cutsaída.
Você pode usar o slurp com o POSIX Awk:
cut -b1 file | awk 'BEGIN{RS="";getline<"-";print>ARGV[1]}' file
Bem, como cutproduz menos saída do que lê, você pode:
cut -c1 < file 1<> file
Ou seja, torne o stdin fileaberto no modo somente leitura e o stdout fileaberto no modo leitura + gravação sem truncamento ( <>).
Dessa forma, cutapenas substituirá o arquivo por si próprio. No entanto, ele deixará o restante do arquivo intocado. Por exemplo, se filecontém:
foo
bar
A saída se tornará:
f
b
bar
Eles f\nb\nforam substituídos foo\n, mas barainda estão lá. Você precisaria truncar o arquivo após a cutconclusão.
Com ksh93, você pode fazê-lo com seu <>;operador, que age como <>exceto, se o comando for bem-sucedido, ftruncate()é chamado no descritor de arquivo. Então:
cut -c1 < file 1<>; file
Com outras conchas, você precisaria fazer isso ftruncate()através de outros meios, como:
{ cut -c1 < file; perl -e 'truncate STDOUT, tell STDOUT';} 1<> file
embora invocar perlapenas para isso seja um pouco exagerado aqui, especialmente considerando que perlpode facilmente fazer esse cuttrabalho, como:
perl -pi -e '$_ = substr($_, 0, 1)' file
Lembre-se de que, com todos os métodos que envolvem a reescrita no local real, se a operação for interrompida no meio do caminho, você acabará com um arquivo corrompido. O uso de um segundo arquivo temporário evita esse problema.
.oldmétodo para mudanças no local,echo "$(cut -d , -f 1,3 <foo)" > foo