Обміняйте вміст двох файлів


13

Це питання з кодовим гольфом. Потрібно взяти вміст двох окремих файлів (i.txt та o.txt) і поміняти їх. Ви можете створити третій файл, який допоможе вам у процесі, але змусіть програму видалити його після заміни вмісту файлу. Перейменування файлів тепер дозволено знову.

Програми повинні працювати для будь-якого файлового вмісту.

Найкоротший код виграє, всі відповідні подання будуть прийняті на голосування.


2
Перейменуйте файли. Не потрібно «брати вміст» і обмінювати їх, щоб досягти результату.
Даррен Стоун

@Darren Stone Я думаю, що це має бути незаконним. Дякуємо, що зрозуміли, перш ніж надходити відповіді.

Схоже, це погане обмеження, перейменування - найкращий спосіб зробити це
hdante

1
Добре, я можу зняти це обмеження.

6
@hdante, але "перейменування файлів" не обмінюється їх вмістом . У системі, яка використовує inodes, ціллю тут є, щоб i.txt's inodeмістив дані з o.txt' s inode, і навпаки, так що, якщо є жорсткі посилання на ці inodeмісця, їхній вміст буде також помінятися. Перейменування цього не може досягти.
AJMansfield

Відповіді:


9

зш, 20

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

1
Я як один без тимчасовий файл краще, хоча: i=`<i.txt`;<o*>i*;<<<$i>o*. Дуже погано, що це повинно бути коротшим.
Ри-

1
Правила змінено, щоб дозволити перейменування файлів. Ви можете оновити свій код, якщо бажаєте.

Ви можете зберегти 3 символи, замінивши <t>o*;rm tна mv t o*!
Ф. Хаурі

@ F.Hauri: А, дякую! (Були правила проти перейменування в одній точці.)
Рибаков

Цей код невірний. Він працює лише в спеціальному випадку, коли i * і o * будуть відповідати лише i.txt і o.txt відповідно, тобто немає іншого файлу з іменем, що починається з "i" або "o".
Ерван Легранд

3

Пітона, 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)

Пітона, 65

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

Пітона, 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");?>

Пакетний файл Windows, 42

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

Пакетний файл Windows (аргументи), 30

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

Я не знав, що ви можете використовувати $r=renameдля створення псевдонімів до функцій PHP. Спасибі!
AL

2

Два на базі; 52 та 62 символи

оболонка: diff + латка (+ tee + sed ...) 52

Можливо, не коротше, але мені це цікаво (і тимчасовий файл не використовується ):

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

Якщо вміст обміняється і файли змінюються на місці :

Вибірка зразка

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

Може створити щось на кшталт:

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

використання xargs для спрощення mv запитів

Не так смішно, але все одно приємно.

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

Зауваження: Оскільки вихід першого патчу не перенаправлений, вони стають сміттям для другої команди патча. Це причина тому, що patching file o.txtз'являється лише одна .
Ф. Хаурі

2

PHP, 89

Я думав, що сфотографую.

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

Негольована версія:

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

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

Мабуть, я взяв тут 2 відповіді і поєднав їх .. ой добре.


2

Рубін, 72 байти

Оце Так! Рубін гольф-код! Я не думаю, що цього ніколи не намагалися робити!

В реальності, однак, для цього знадобилися кілька приємних ярликів Рубі та кілька моделей, які я знайшов. Це був мій перший гольф коли-небудь, і це було дуже весело робити. Без зайвих помилок, ось код для гольфу:

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

І нелюбова версія

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

Ключовий фактор у цьому полягає в тому, що параметри, передані до параметра File.rename, це саме такі:

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

Сподіваюся, це (не) має сенс!


2

Powershell, 44 49 байт

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

де renпсевдонім для перейменування-елемента . Сценарій використовує та видаляє третій файл a.txt.


1
Це може не вдатися до певного кодування. Оскільки gcза замовчуванням є UTF8NoBOM, але scза замовчуванням - ASCII. Спробуйте кілька файлів UTF-8 або бінарних файлів, і ви можете побачити, як це може вийти з ладу.
AdmBorkBork

Справді. Спасибі. Йому потрібні -e by -nпараметри, щоб забезпечити незмінність файлів. Було б непогано додати параметр -readCount 0продуктивності. Сценарій з renameкоротшим :) Виправлено.
маззи

1

Рубін

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

Скорочена версія:

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

Не найкоротший, але дуже простий і легкий для читання. Також немає проміжних файлів, лише ОЗУ.


1
Зважаючи на те, що це кодовий гольф , ви можете принаймні вийняти місця і спробувати дещо для найкоротших.
Ри-

Повністю не зрозумів, що це код-гольф, вибачте

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
Thats не дуже гофро :(
Jakob Bowyer

1

Сценарій оболонки, 24

Працює в Баші і, мабуть, більшість снарядів. Передайте дві параметри файлів як параметри.

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

Якщо ви хочете виправити імена файлів, це зробить це, за штраф 12 знаків:

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

@minitech, так, це так. 'ੴ' стає 'o.txt'. Це mvоперації, а не cp.
Даррен Стоун

Друга найкраща відповідь поки! Скоротіть його на два символи, і ви виграєте! Мене не хвилюють фіксовані імена файлів.


1

Пакетний файл Windows (48)

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

Я забув про команду переміщення, коли написав це ...


Ви просто перезаписали мій aфайл!
Денні

@Danny У запитанні вказано, що ви можете створити інший файл, але його потрібно видалити.
kitcar2000

1

C 162

Golfed: використовує t.txt як tmp-файл і замінює імена, після чого видаляє 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;}

Редагувати: видалено 2 пробіли


1

PHP - 172

Гольф-версія відповіді @ 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 (перейменувати файл) або 55 (вміст r / w)

Перейменуйте файл (використовуючи tяк тимчасовий файл):

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

Прочитайте, а потім випишіть вміст файлу:

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

Не дуже гофрований, але найкоротший PHP поки що.


файлові розширення відсутні.
Тит

1

Groovy - 99 символів

Це моя спроба, з Groovy 2.2.1. Я намагався це зробити без перейменування:

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

Безголівки:

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) та (126 ... 110)

Перейменування з тимчасовим файлом t на диску c: \. Також перша спроба гольфу: 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

Якщо на scrrun.dll вже посилається, може скоротити його трохи до 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

Схоже, ваш код має багато пробілів. Ви впевнені, що вони потрібні? Якщо ви видалите їх, ви можете мати набагато кращий результат.
користувач12205

Я не думаю, що це потрібно, редактор просто кинув його. Видалено крім того, де це потрібно :)
jaybee3

1

C: 65 символів

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

Досить просте рішення в C, яке робить роботу. Він використовує тимчасове ім'я ( .txt) для одного з файлів, перш ніж присвоїти йому власне нове ім'я.

Ungolfed (зверніть увагу на те, як підсвічування синтаксису не вдається визначити, помилка виявлена!):

#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 байт (зміна вмісту без перейменування файлів)

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

Вміст файлу зберігається в пам'яті і записується в інший файл. Таким чином i.txtі o.txtповинен вписатися в пам'ять.

Оскільки вміст файлу фактично обмінюється, жорсткі посилання оновлюються автоматично, дивіться коментар AJManfield .

Безголівки:

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

Луа ,71 70 байт

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

Спробуйте в Інтернеті!

Визначте osбібліотеку операційної системи як глобальну таблицю, щоб ми могли писати renameі removeзамість os.renameі os.remove. (Між іншим, це також означає, що однобукве змінні - це фактично поля в osтаблиці.) Складіть короткі псевдоніми, os.renameщоб заощадити місце. Налаштуйте змінні назви файлів, використовуючи '.txt'як тимчасовий файл. Зробіть перейменування та видалення.




Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.