Troque o conteúdo de dois arquivos

13

Esta é uma questão de código-golfe. Você precisa pegar o conteúdo de dois arquivos separados (i.txt e o.txt) e trocá-los. Você pode criar um terceiro arquivo para ajudá-lo no processo, mas seu programa o exclui após a troca do conteúdo do arquivo. Renomear os arquivos agora é permitido novamente.

Os programas devem funcionar para qualquer conteúdo de arquivo.

Se o código mais curto vencer, todos os envios elegíveis serão votados positivamente.


fonte
2
Renomeie os arquivos. Não é necessário "pegar o conteúdo" e trocá-lo para obter o resultado.
Darren Pedra
@ Darren Stone Eu acho que isso deveria ser ilegal. Obrigado por capturar isso antes que as respostas fossem enviadas.
Parece um mau restrição, renomeação é a melhor maneira de fazer isso
hdante
1
Tudo bem, eu posso remover essa restrição.
6
@hdante, mas 'renomear arquivos' não está trocando seu conteúdo . Em um sistema que usa inodes o objetivo aqui seria para i.txté inodepara conter os dados de o.txt's inode, e vice-versa, de modo que se houver hardlinks àqueles inodeé em outro lugar, seu conteúdo será apresentado trocados também. Renomear não pode fazer isso.
AJMansfield

Respostas:

9

zsh, 20

<i*>t;<o*>i*;mv t o*
Ry-
fonte
1
Eu como o que, sem um arquivo temporário melhor, no entanto: i=`<i.txt`;<o*>i*;<<<$i>o*. É uma pena que isso tenha que ser mais curto.
Ry-
1
Regras alteradas para permitir renomear arquivos. Você pode atualizar seu código, se desejar.
Você pode salvar 3 caracteres substituindo <t>o*;rm tpor mv t o*!
F. Hauri
@ F.Hauri: Ah, obrigado! (Havia regras contra renomear em um ponto.)
Ry-
Este código não está correto. Funciona apenas no caso especial em que i * e o * corresponderão apenas a i.txt e o.txt, respectivamente, ou seja, não há outro arquivo com um nome que comece com "i" ou "o".
Erwan Legrand
3

Python, 77

import os;t='.txt';r,i,o,x=[os.rename,'i'+t,'o'+t,'1'+t];r(i,x);r(o,i);r(x,o)

Python, 65

import os;t='.txt'
for a,b in zip('iox','xio'):os.rename(a+t,b+t)

Python, 63

import os;t='.txt'
for a,b in 'ix','oi','xo':os.rename(a+t,b+t)

PHP, 68

<?$r=rename;$t='.txt';$r("i$t","x");$r("o$t","i$t");$r("x","o$t");?>

Arquivo em lote do Windows, 42

move i.txt x&move o.txt i.txt&move x o.txt

Arquivo em lote do Windows (args), 30

move %1 x&move %2 %1&move x %2
AsksAnyway
fonte
Eu não sabia que você pode usar $r=renamepara criar aliases para funções em PHP. Obrigado!
AL
2

Dois ansers baseados em ; 52 e 62 caracteres

shell: diff + patch (+ tee + sed ...) 52

Talvez não seja o mais curto, mas acho isso divertido (e não há uso de arquivo temporário ):

diff -u [io]*|tee >(patch -r -)|sed 1s/i/o/|patch -R

Onde o conteúdo é trocado e os arquivos são modificados no local :

Execução de amostra

swapContent() { diff -u $1 $2|tee >(patch -r -)|sed 1s/$1/$2/|patch -R ;}

while read page file ;do man -Pcol\ -b $page >$file.txt;done <<<$'man i\nbash o'
printf "%s %8d  %s\n" $(join -j 2 <(stat -c '%s %n' [io]*) <(md5sum [io]*))
swapContent [io]*
printf "%s %8d  %s\n" $(join -j 2 <(stat -c '%s %n' [io]*) <(md5sum [io]*))

Pode produzir algo como:

i.txt    46007  1da1f7533e0eab1e97cce97bb7ca1d3b
o.txt   321071  7dcd230890faf4ef848d4745eda14407
patching file o.txt
i.txt   321071  7dcd230890faf4ef848d4745eda14407
o.txt    46007  1da1f7533e0eab1e97cce97bb7ca1d3b

uso de xargs para simplificar mv solicitações

Não é tão engraçado, mas agradável de qualquer maneira.

set -- {i,o}.txt t&&eval 'xargs -n2 mv<<<"' \${1,3,2,1,3,2} \"
F. Hauri
fonte
Nota: Como a saída do primeiro patch não é redirecionada, eles se tornam lixo no segundo comando do patch. Este é o motivo, porque apenas um patching file o.txtaparece.
F. Hauri
2

PHP, 89

Eu pensei em tentar.

<?php $f1='f1.txt';$f2='f2.txt';$ft='ft.txt';copy($f1,$ft);copy($f2,$f1);rename($ft,$f2);

Versão não destruída:

<?php
$f1 = 'f1.txt';
$f2 = 'f2.txt';
$ft = 'ft.txt';

copy($f1, $ft);
copy($f2, $f1);
rename($ft, $f2);

Aparentemente, peguei 2 respostas aqui e as combinei .. tudo bem.

MisterBla
fonte
2

Ruby, 72 bytes

Uau! Um código de golfe Ruby! Acho que nunca foi tentado antes!

Em toda a realidade, porém, isso exigiu alguns bons atalhos de Ruby e alguns padrões que eu encontrei. Foi o meu primeiro golfe e foi muito divertido de fazer. Sem mais delongas, aqui está o código do golfe:

3.times{|x|x*=2;t=".txt";a=([?i,?a,?o]*2);File.rename(a[x]+t,a[x+1]+t)}

E a versão ungolfed

3.times do |x|
    x = x * 2
    t=".txt"
    a=([?i,?a,?o]*2)
    File.rename(a[x]+t, a[x+1]+t)}
end

O fator chave nisso é que os parâmetros passados ​​para File.renamesão exatamente isso:

File.rename "i.txt", "a.txt"
File.rename "o.txt", "i.txt"
File.rename "a.txt", "o.txt"

Espero que isso (não) faça sentido!

Aearnus
fonte
2

Powershell, 44 49 bytes

$t='.txt'
ren i$t a$t -fo
ren o$t i$t
ren a$t o$t

onde rené o alias para Renomear-Item . O script usa e exclui um terceiro arquivo a.txt.

confuso
fonte
1
Isso pode falhar com determinadas codificações. Como o gcpadrão é UTF8NoBOM, mas o scpadrão é ASCII. Experimente alguns arquivos UTF-8 ou arquivos binários e você poderá ver como isso pode falhar.
AdmBorkBork
De fato. Obrigado. Ele precisa de -e by -nparâmetros para garantir que os arquivos não sejam alterados. Seria bom adicionar um parâmetro -readCount 0ao desempenho. O script com renameé mais curto :) Corrigido.
Mazzy
1

Rubi

i1="i.txt"
i2="o.txt"
c1=IO.readlines(i2)
c2=IO.readlines(i1)
File.open(i1){|x|x.puts(c1)}
File.open(i2){|x|x.puts(c2)}

Versão abreviada:

a=["i.txt","o.txt"]
(0..1).each{|x|b[x]=IO.readlines(a[x])*"\n"}
a.reverse!
(0..1).each{|x|IO.write(a[x],b[x])}

Não é o mais curto, mas muito simples e fácil de ler. Além disso, não há arquivos intermediários, apenas RAM.


fonte
1
Dado que é um código de golfe , você pode pelo menos ocupar os espaços e tentar um pouco pelo menos.
Ry-
Totalmente não percebi que era code-golf, desculpe #
1

PHP

$f1 = 'file1.txt';
$f2 = 'file2.txt';

$f1contents = file_get_contents ($f1);
$f2contents = file_get_contents ($f2);

file_put_contents($f1, $f2contents);
file_put_contents($f2, $f1contents);
Eisa Adil
fonte
10
Isso não é realmente golfe :(
Jakob Bowyer
1

Script de shell, 24

Funciona no Bash e provavelmente na maioria das conchas. Passe com seus dois nomes de arquivos como parâmetros.

mv $1 ੴ;mv $2 $1;mv ੴ $2

Se você quiser nomes de arquivos fixos, será o caso, por uma penalidade de 12 caracteres:

mv i.txt ੴ;mv o.txt i.txt;mv ੴ o.txt
Darren Stone
fonte
@ Minitech, sim. 'ੴ' se torna 'o.txt'. Essas são mvoperações, não cp.
Darren Pedra
Segunda melhor resposta até agora! Reduza-o em dois caracteres e você ganha! Eu não ligo para nomes de arquivos fixos.
1

Pitão:

import os
l,e='i_o'*2,'.txt'
for x,y in zip(l,l[1:])[::2]:
 os.rename(x+e,y+e)
tamasgal
fonte
1

Arquivo em lote do Windows (48)

type i.txt>a&type o.txt>i.txt&type a>o.txt&del a

Eu esqueci o comando mover quando escrevi isso ...

kitcar2000
fonte
Você acabou de substituir meu aarquivo!
Danny
@ Danny A questão afirma que você pode criar outro arquivo, mas ele deve ser excluído.
Kitcar2000
1

C 162

Golfe: usa t.txt como arquivo tmp e troca nomes, depois remove t.txt.

#include <stdio.h>
#define R(x,y) rename(x,y)
#define X(x) remove(x)
int main(){char *i="i.txt",*o="o.txt",*t="t.txt";R(i,t);X(i);R(o,i);R(t,o);X(t);return 0;}

Editar: 2 espaços removidos

bacchusbeale
fonte
1

PHP - 172

Versão golfe da resposta de @ EisaAdil

$f1='file1.txt';$f2='file2.txt';$f1contents=file_get_contents($f1);$f2contents=file_get_contents($f2);file_put_contents($f1,$f2contents);file_put_contents($f2,$f1contents);
Spedwards
fonte
1

Rebol - 46 (renomear arquivo) ou 55 (conteúdo em r / w)

Renomeie o arquivo (usando tcomo arquivo temporário):

r: :rename 
r i: %i.txt %t
r o: %o.txt i
r %t o

Leia e escreva o conteúdo do arquivo:

a: read i: %i.txt
b: read o: %o.txt
write o a 
write i b
draegtun
fonte
1

PHP, 45

<?php
copy('i','t');copy('o','i');rename('t','o');

Não é muito golfy, mas o PHP mais curto até agora.

mleko
fonte
estão faltando extensões de arquivo.
Titus
1

Groovy - 99 caracteres

Esta é a minha tentativa, com o Groovy 2.2.1. Eu tentei fazer isso sem renomear:

f={new File(it+".txt")}
w={x,y->x.withWriter{it.write y}}
i=f "i"
o=f "o"
t=i.text
w i,o.text
w o,t

Ungolfed:

file = { new File(it+".txt") }
writeTextToFile = { x,y -> x.withWriter{it.write y} }

iFile = file("i")
oFile = file("o")

iText = iFile.text
writeTextToFile (iFile,oFile.text)
writeTextToFile (oFile,iText)
Michael Easter
fonte
1

VBA (148 ... 132) e (126 ... 110)

Renomeando com um arquivo temporário t na unidade c: \. Também primeira tentativa de golfe: S

Sub s():Set f=CreateObject("Scripting.FileSystemObject"):i="c:\i.txt":t="c:\t":f.MoveFile i,t:f.MoveFile "c:\o.txt",i:Kill t:End Sub

Se o scrrun.dll já estiver mencionado, poderá reduzir um pouco para 126 ... 110.

Sub s():Set f=new FileSystemObject:i="c:\i.txt":t="c:\t":f.MoveFile i,t:f.MoveFile "c:\o.txt",i:Kill t:End Sub
jaybee3
fonte
Parece que seu código possui muito espaço em branco. Tem certeza de que eles são necessários? Você pode ter uma pontuação muito melhor se removê-los.
User12205
Eu não acho que seja necessário o editor simplesmente a jogou no Removido para além de onde é necessário :).
jaybee3
1

C: 65 caracteres

#define r(a,b)rename(#a".txt",#b".txt");
main(){r(i,)r(o,i)r(,o)}

Uma solução bastante simples em C que faz o trabalho. Ele usa um nome temporário ( .txt) para um dos arquivos antes de atribuir seu novo nome adequado.

Ungolfed (observe como o realce da sintaxe falha na definição, um bug foi descoberto!):

#include <stdio.h>

#define r(a, b) rename(#a ".txt", #b ".txt");

int main()
{
    r(i,  ) // rename("i.txt",  ".txt");
    r(o, i) // rename("o.txt", "i.txt");
    r( , o) // rename( ".txt", "o.txt");

    return 0;
}
Para s
fonte
1

Perl, 120 bytes (troca de conteúdo sem renomear arquivos)

use open IO,':bytes';undef$/;open I,"<i.txt";$I=<I>;open I,"<o.txt";open O,">i.txt";print O<I>;open O,">o.txt";print O$I

O conteúdo do arquivo é colocado na memória e gravado de volta no outro arquivo. Assim i.txte o.txtdeve caber na memória.

Como o conteúdo do arquivo é realmente trocado, os links físicos são atualizados automaticamente, consulte o comentário do AJManfield .

Ungolfed:

use open IO => ':bytes'; # binmode, not needed for Unix, but needed for Windows
undef $/;                # read whole file instead of lines
open I, "<i.txt";        # open i.txt for reading
$I = <I>;                # read i.txt
open I, "<o.txt";        # open o.txt for reading
open O, ">i.txt";        # open i.txt for writing
print O <I>;             # read o.txt and put the contents in i.txt
open O, ">o.txt";        # open o.txt for writing
print O $I;              # write o.txt with contents of old i.txt
Heiko Oberdiek
fonte
1

Lote do Windows, 39 bytes

ren i.txt x&ren o.txt i.txt&ren x o.txt
Peter Ferrie
fonte
1

Lua ,71 70 bytes

_ENV=os t='.txt'i,o,r='i'..t,'o'..t,rename r(i,t)r(o,i)r(t,o)remove(t)

Experimente online!

Defina os, a biblioteca do sistema operacional, como a tabela global para que possamos escrever renamee em removevez de os.renamee os.remove. (Aliás, isso também significa que as variáveis ​​de uma letra são realmente campos da ostabela.) Crie um apelido curto para os.renameeconomizar espaço. Configure variáveis ​​de nome de arquivo, usando '.txt'como arquivo temporário. Renomeie e exclua.

ciclaminista
fonte
1

PHP, 52 bytes

O php de AsksAnyway modernizado e jogado:

($r=rename)(i.$e=".txt",x);$r(o.$e,i.$e);$r(x,o.$e);

Corra com php -nr '<code>'.

Titus
fonte
1

Tcl , 122 bytes

set A [read [open i.txt]]
puts [set i [open i.txt w]] [read [open o.txt]]
puts [set o [open o.txt w]] $A
close $i
close $o

Experimente online!


Tcl , 169 bytes

set A [read [set i [open i.txt r]]]
set B [read [set o [open o.txt r]]]
close $i
close $o
puts [set i [open i.txt w]] $B
puts [set o [open o.txt w]] $A
close $i
close $o

Experimente online!

sergiol
fonte
0

SmileBASIC, 36 35 bytes

@L
RENAME@OI[2-I],@IO[I]I=I+1GOTO@L
12Me21
fonte