Scambia il contenuto di due file


13

Questa è una domanda di code-golf. Devi prendere il contenuto di due file separati (i.txt e o.txt) e scambiarli. Puoi creare un terzo file per aiutarti con il processo, ma fai in modo che il tuo programma lo elimini dopo lo scambio del contenuto del file. La ridenominazione dei file ora è di nuovo consentita.

I programmi devono funzionare per qualsiasi contenuto di file.

Il codice più corto vince, tutti gli invii idonei verranno votati.


2
Rinomina i file. Non è necessario "prendere i contenuti" e scambiarli per ottenere il risultato.
Darren Stone,

@Darren Stone Penso che dovrebbe essere illegale. Grazie per averlo scoperto prima che le risposte fossero inviate.

Sembra un brutto vincolo, rinominare è il modo migliore per farlo
hdante,

1
Bene, posso rimuovere questo vincolo.

6
@hdante ma 'rinominare i file' non sta scambiando i loro contenuti . Su un sistema che utilizza inodes l'obiettivo qui sarebbe per i.txt's inodeper contenere i dati da o.txt' s inode, e viceversa, in modo che se ci sono collegamenti fisici a quelli inodes altrove, il loro contenuto appariranno scambiati pure. La ridenominazione non può farlo.
AJMansfield,

Risposte:


9

zsh, 20

<i*>t;<o*>i*;mv t o*

1
Mi piace l'uno senza un file temporaneo meglio, però: i=`<i.txt`;<o*>i*;<<<$i>o*. Peccato che questo debba essere più breve.
Ry,

1
Le regole sono state modificate per consentire la ridenominazione dei file. Puoi aggiornare il tuo codice se lo desideri.

Puoi salvare 3 caratteri sostituendoli <t>o*;rm tcon mv t o*!
F. Hauri,

@ F.Hauri: Ah, grazie! (A un certo punto c'erano regole contro la ridenominazione.)
Ry

Questo codice non è corretto Funziona solo nel caso speciale in cui i * e o * corrisponderanno rispettivamente solo a i.txt e o.txt, ovvero non esiste un altro file con un nome che inizia con "i" o "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 anni

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");?>

File batch di Windows, 42

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

File batch di Windows (args), 30

move %1 x&move %2 %1&move x %2

Non sapevo che puoi usare $r=renameper creare alias per le funzioni in PHP. Grazie!
AL

2

Due risposte basate su ; 52 e 62 caratteri

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

Forse non il più breve, ma lo trovo divertente (e non c'è alcun file temporaneo ):

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

Dove il contenuto viene scambiato e i file vengono modificati in atto :

Esecuzione del campione

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]*))

Potrebbe produrre qualcosa di simile:

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

uso di xargs per semplificare mv richieste

Non altrettanto divertente, ma comunque carino.

set -- {i,o}.txt t&&eval 'xargs -n2 mv<<<"' \${1,3,2,1,3,2} \"

Nota: poiché l'output della prima patch non viene reindirizzato, diventano immondizia al secondo comando patch. Questo è il motivo perché ne patching file o.txtappare solo uno .
F. Hauri,

2

PHP, 89

Ho pensato di provarci.

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

Versione non golfata:

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

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

Apparentemente ho preso 2 risposte da qui e le ho combinate .. vabbè.


2

Rubino, 72 byte

Wow! Un golf con codice Ruby! Non credo che sia mai stato tentato prima!

In tutta la realtà, tuttavia, ciò ha richiesto alcune belle scorciatoie Ruby e un paio di modelli che ho trovato. È stato il mio primo golf in assoluto ed è stato molto divertente da fare. Senza ulteriori indugi, ecco il codice golf:

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

E la versione non golfata

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

Il fattore chiave in questo è che i parametri passati a File.renamesono esattamente questi:

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

Spero che questo (non) abbia senso!


2

Powershell, 44 49 byte

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

dove si rentrova l'alias per Rename-Item . Lo script utilizza ed elimina un terzo file a.txt.


1
Questo può fallire con una certa codifica. Perché il gcvalore predefinito è UTF8NoBOM ma il scvalore predefinito è ASCII. Prova alcuni file UTF-8 o file binari e puoi vedere come può fallire.
AdmBorkBork,

Infatti. Grazie. Sono necessari -e by -nparametri per garantire che i file siano invariati. Sarebbe bello aggiungere un parametro -readCount 0alle prestazioni. Lo script con renameè più breve :) Risolto.
mazzy,

1

Rubino

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)}

Versione abbreviata:

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])}

Non il più breve, ma molto semplice e facile da leggere. Inoltre, nessun file intermedio, solo RAM.


1
Dato che si tratta di un codice-golf , potresti almeno eliminare gli spazi e provare un po 'per il più breve.
Ry,

Totalmente non mi rendevo conto che si trattava di code-golf, scusate

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);

10
Quello non è davvero da golf :(
Jakob Bowyer il

1

Script di shell, 24

Funziona in Bash e probabilmente nella maggior parte delle shell. Passa con i tuoi due nomi di file come parametri.

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

Se vuoi nomi di file fissi, questo lo farà, con una penalità di 12 caratteri:

mv i.txt ੴ;mv o.txt i.txt;mv ੴ o.txt

@minitech, sì, lo fa. 'ੴ' diventa 'o.txt'. Quelle sono mvoperazioni, no cp.
Darren Stone,

La seconda migliore risposta finora! Riducilo di due personaggi e vinci! Non mi importa dei nomi di file fissi.

1

Pitone:

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

1

File batch di Windows (48)

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

Ho dimenticato il comando di spostamento quando ho scritto questo ...


Hai appena sovrascritto il mio afile!
Danny,

@Danny La domanda indica che è possibile creare un altro file, ma deve essere eliminato.
kitcar2000,

1

C 162

Golf: usa t.txt come file tmp e scambia i nomi, quindi rimuove 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;}

Modifica: rimosso 2 spazi


1

PHP - 172

Versione golfata della risposta di @ 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);

1

Rebol - 46 (rinomina file) o 55 (contenuto r / w)

Rinomina file (usando tcome file temporaneo):

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

Leggi e poi scrivi il contenuto del file:

a: read i: %i.txt
b: read o: %o.txt
write o a 
write i b

1

PHP, 45

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

Finora non molto golfy ma PHP più breve.


mancano le estensioni di file.
Tito

1

Groovy - 99 caratteri

Questo è il mio tentativo, con Groovy 2.2.1. Ho provato a farlo senza rinominare:

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)

1

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

Rinominare con un file temporaneo t nell'unità c: \. Anche il primo tentativo di golf: 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 si fa già riferimento a scrrun.dll, potrebbe ridurlo un po 'a 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

Sembra che il tuo codice abbia molto spazio bianco. Sei sicuro che siano necessari? Puoi ottenere un punteggio molto migliore se li rimuovi.
user12205,

Non credo sia necessario che l'editor l'abbia appena lanciato. Rimosso a parte dove è necessario :)
jaybee3

1

C: 65 caratteri

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

Una soluzione abbastanza semplice in C che fa il lavoro. Utilizza un nome temporaneo (.txt ) per uno dei file prima di assegnargli il nuovo nome.

Ungolfed (nota come l'evidenziazione della sintassi non riesce nella definizione, un bug è stato scoperto!):

#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;
}

1

Perl, 120 byte (scambio di contenuti senza rinominare i file)

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

Il contenuto del file viene messo in memoria e riscritto nell'altro file. Quindi i.txte o.txtdeve adattarsi alla memoria.

Poiché il contenuto del file viene effettivamente scambiato, i collegamenti fisici vengono aggiornati automaticamente, vedere il commento di 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


1

Lua ,71 70 byte

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

Provalo online!

Definire osla libreria del sistema operativo come tabella globale in modo che possiamo scrivere renamee removeinvece di os.renamee os.remove. (Per inciso, ciò significa anche che le variabili di una lettera sono in realtà campi nella ostabella.) Crea un breve alias per os.renamerisparmiare spazio. Imposta le variabili del nome file, usando '.txt'come file temporaneo. Esegui la ridenominazione e l'eliminazione.



1

Tcl , 122 byte

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

Provalo online!


Tcl , 169 byte

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

Provalo online!


0

SmileBASIC, 36 35 byte

@L
RENAME@OI[2-I],@IO[I]I=I+1GOTO@L
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.