W poniższych odpowiedziach pamiętaj, że wszelkie zalecenia, których należy użyć, File.readnależy złagodzić informacjami ze stackoverflow.com/a/25189286/128421, wyjaśniającymi, dlaczego siorbanie dużych plików jest złe. Również zamiast File.open(filename, "w") { |file| file << content }odmian użyj File.write(filename, content).
Tin Man
Odpowiedzi:
190
Zastrzeżenie: To podejście jest naiwną ilustracją możliwości Rubiego, a nie rozwiązaniem do zastępowania ciągów w plikach na poziomie produkcyjnym. Jest podatny na różne scenariusze awarii, takie jak utrata danych w przypadku awarii, przerwania lub zapełnienia dysku. Ten kod nie nadaje się do niczego poza szybkim, jednorazowym skryptem, w którym wszystkie dane są archiwizowane. Z tego powodu NIE kopiuj tego kodu do swoich programów.
Oto krótki krótki sposób, aby to zrobić.
file_names =['foo.txt','bar.txt']
file_names.each do|file_name|
text =File.read(file_name)
new_contents = text.gsub(/search_regexp/,"replacement string")# To merely print the contents of the file, use:
puts new_contents# To write changes to the file, use:File.open(file_name,"w"){|file| file.puts new_contents }end
Aby zapisać plik, zamień wiersz puts naFile.write(file_name, text.gsub(/regexp/, "replace")
ciasny
106
W rzeczywistości Ruby ma funkcję edycji lokalnej. Możesz powiedzieć, jak Perl
ruby -pi.bak -e "gsub(/oldtext/, 'newtext')"*.txt
Spowoduje to zastosowanie kodu w cudzysłowach do wszystkich plików w bieżącym katalogu, których nazwy kończą się na „.txt”. Kopie zapasowe edytowanych plików zostaną utworzone z rozszerzeniem „.bak” (chyba „foobar.txt.bak”).
UWAGA: wygląda na to, że nie działa w przypadku wyszukiwania wielowierszowego. W tym przypadku musisz zrobić to w inny mniej ładny sposób, stosując skrypt opakowujący wokół wyrażenia regularnego.
Co to do cholery jest pi.bak? Bez tego pojawia się błąd. -e: 1: in <main>': undefined method gsub 'dla main: Object (NoMethodError)
Ninad
15
@NinadPachpute -iedytuje w miejscu. .bakto rozszerzenie pliku kopii zapasowej (opcjonalnie). -pjest czymś w rodzaju while gets; <script>; puts $_; end. ( $_to ostatnia przeczytana linia, ale możesz przypisać do niej coś w rodzaju echo aa | ruby -p -e '$_.upcase!'.)
Lri
1
To lepsza odpowiedź niż zaakceptowana odpowiedź, IMHO, jeśli chcesz zmodyfikować plik.
Colin K,
6
Jak mogę tego użyć w skrypcie ruby?
Saurabh
1
Istnieje wiele sposobów, w jakie może to się nie udać, więc przetestuj go dokładnie, zanim spróbujesz go z plikiem krytycznym.
Tin Man
49
Pamiętaj, że kiedy to zrobisz, w systemie plików może zabraknąć miejsca i możesz utworzyć plik o zerowej długości. Jest to katastrofalne, jeśli robisz coś takiego jak wypisywanie plików / etc / passwd w ramach zarządzania konfiguracją systemu.
Zwróć uwagę, że edycja plików w miejscu, taka jak w zaakceptowanej odpowiedzi, zawsze spowoduje obcięcie pliku i sekwencyjne wypisanie nowego pliku. Zawsze wystąpi sytuacja wyścigu, w której współbieżni czytelnicy zobaczą obcięty plik. Jeśli proces zostanie przerwany z jakiegokolwiek powodu (ctrl-c, OOM killer, awaria systemu, awaria zasilania itp.) Podczas zapisu, to obcięty plik również zostanie pozostawiony, co może być katastrofalne. Jest to rodzaj scenariusza utraty danych, który programiści MUSZĄ wziąć pod uwagę, ponieważ tak się stanie. Z tego powodu uważam, że zaakceptowana odpowiedź najprawdopodobniej nie powinna być zaakceptowaną odpowiedzią. Jako minimum napisz do pliku tymczasowego i przenieś / zmień nazwę pliku na miejsce, tak jak w „prostym” rozwiązaniu na końcu tej odpowiedzi.
Musisz użyć algorytmu, który:
Odczytuje stary plik i zapisuje do nowego pliku. (Musisz uważać na wrzucanie całych plików do pamięci).
Jawnie zamyka nowy plik tymczasowy, w którym można zgłosić wyjątek, ponieważ nie można zapisać buforów plików na dysku, ponieważ nie ma miejsca. (Złap to i wyczyść plik tymczasowy, jeśli chcesz, ale musisz w tym momencie coś ponownie wrzucić lub dość mocno zawieść.
Naprawia uprawnienia do plików i tryby w nowym pliku.
Zmienia nazwę nowego pliku i umieszcza go na miejscu.
Dzięki systemom plików ext3 masz gwarancję, że metadane zapisywane w celu przeniesienia pliku na miejsce nie zostaną przestawione przez system plików i zapisane przed zapisaniem buforów danych dla nowego pliku, więc powinno to się powieść lub zakończyć niepowodzeniem. System plików ext4 również został załatany, aby obsługiwał tego typu zachowanie. Jeśli jesteś bardzo paranoikiem, powinieneś wywołać wywołanie fdatasync()systemowe w kroku 3.5 przed przeniesieniem pliku na miejsce.
Niezależnie od języka jest to najlepsza praktyka. W językach, w których wywołanie close()nie zgłasza wyjątku (Perl lub C), należy jawnie sprawdzić wynik close()i zgłosić wyjątek, jeśli się nie powiedzie.
Powyższa sugestia, aby po prostu wsypać plik do pamięci, manipulować nim i zapisać go do pliku, gwarantuje utworzenie plików o zerowej długości na pełnym systemie plików. Trzeba zawsze używać FileUtils.mvdo poruszania się w pełni napisany plik tymczasowy na miejscu.
Ostatnią kwestią jest umieszczenie pliku tymczasowego. Jeśli otworzysz plik w / tmp, musisz wziąć pod uwagę kilka problemów:
Jeśli / tmp jest zamontowany w innym systemie plików, możesz uruchomić / tmp bez miejsca przed wypisaniem pliku, który w innym przypadku byłby możliwy do wdrożenia w miejscu docelowym starego pliku.
Prawdopodobnie ważniejsze jest to, że kiedy spróbujesz mvprzenieść plik na urządzenie, zostaniesz przekonwertowany na cpzachowanie. Stary plik zostanie otwarty, stary i-węzeł plików zostanie zachowany i ponownie otwarty, a zawartość pliku zostanie skopiowana. Najprawdopodobniej to nie jest to, czego chcesz i możesz napotkać błąd „plik tekstowy zajęty”, jeśli spróbujesz edytować zawartość uruchomionego pliku. To również przeczy celowi używania mvpoleceń systemu plików i możesz uruchomić docelowy system plików bez miejsca, mając tylko częściowo zapisany plik.
Nie ma to również nic wspólnego z implementacją Rubiego. System mvi cppolecenia zachowują się podobnie.
Bardziej preferowane jest otwarcie pliku tymczasowego w tym samym katalogu, w którym znajduje się stary plik. Gwarantuje to, że nie będzie problemów z przenoszeniem między urządzeniami. mvSama nigdy nie uda, i zawsze należy uzyskać pełną i untruncated pliku. Podczas zapisywania pliku tymczasowego należy napotkać wszelkie awarie, takie jak brak miejsca na urządzeniu, błędy uprawnień itp.
Jedyne wady podejścia do tworzenia pliku tymczasowego w katalogu docelowym to:
Czasami możesz nie być w stanie otworzyć tam pliku tymczasowego, na przykład, jeśli próbujesz „edytować” plik w / proc. Z tego powodu możesz chcieć wycofać się i spróbować / tmp, jeśli otwarcie pliku w katalogu docelowym nie powiedzie się.
Musisz mieć wystarczająco dużo miejsca na partycji docelowej, aby pomieścić zarówno cały stary plik, jak i nowy plik. Jednakże, jeśli nie masz wystarczającej ilości miejsca na przechowywanie obu kopii, prawdopodobnie brakuje Ci miejsca na dysku, a rzeczywiste ryzyko zapisania obciętego pliku jest znacznie wyższe, więc uważam, że jest to bardzo słaby kompromis poza wyjątkowo wąskimi (i dobrze -monitored) skrajne przypadki.
Oto kod, który implementuje pełny algorytm (kod systemu Windows jest nieprzetestowany i niedokończony):
A tutaj jest nieco ściślejsza wersja, która nie przejmuje się wszystkimi możliwymi przypadkami skrajnymi (jeśli używasz Uniksa i nie obchodzi Cię pisanie do / proc):
Naprawdę prosty przypadek użycia, gdy nie dbasz o uprawnienia systemu plików (albo nie pracujesz jako root, albo pracujesz jako root i plik należy do administratora):
TL; DR : Powinno to być używane zamiast zaakceptowanej odpowiedzi jako minimum we wszystkich przypadkach, aby mieć pewność, że aktualizacja jest niepodzielna, a współbieżni czytelnicy nie zobaczą obciętych plików. Jak wspomniałem powyżej, utworzenie pliku Temp w tym samym katalogu co edytowany plik jest tutaj ważne, aby uniknąć tłumaczenia operacji mv na różnych urządzeniach na operacje cp, jeśli / tmp jest zamontowany na innym urządzeniu. Wywołanie fdatasync to dodatkowa warstwa paranoi, ale spowoduje to spadek wydajności, więc pominąłem to w tym przykładzie, ponieważ nie jest powszechnie praktykowane.
Zamiast otwierać plik tymczasowy w katalogu, w którym się znajdujesz, w rzeczywistości automatycznie utworzy go w katalogu danych aplikacji (w każdym razie w systemie Windows) iz ich poziomu możesz zrobić plik.unlink, aby go usunąć ..
13aal
3
Naprawdę doceniam dodatkową myśl, która została w to włożona. Dla początkujących bardzo interesujące jest zobaczenie schematów myślowych doświadczonych programistów, którzy nie tylko potrafią odpowiedzieć na oryginalne pytanie, ale także skomentować szerszy kontekst tego, co tak naprawdę oznacza oryginalne pytanie.
ramijames
Programowanie to nie tylko naprawianie bezpośredniego problemu, ale także myślenie z wyprzedzeniem, aby uniknąć innych problemów, które czekają. Nic tak nie irytuje starszego programisty, jak napotkanie kodu, który zamalował algorytm w róg, wymuszając niezręczny bałagan, podczas gdy niewielka wcześniejsza korekta spowodowałaby niezły przepływ. Często analiza celu może zająć godziny lub dni, a następnie kilka wierszy zastępuje stronę ze starym kodem. To jak gra w szachy z danymi i czasami z systemem.
Tin Man
11
Tak naprawdę nie ma sposobu na edycję plików w miejscu. To, co zwykle robisz, kiedy możesz sobie z tym poradzić (tj. Jeśli pliki nie są zbyt duże), to wczytujesz plik do pamięci ( File.read), wykonujesz podstawienia na odczytanym ciągu ( String#gsub), a następnie zapisujesz zmieniony ciąg z powrotem do plik ( File.open, File#write).
Jeśli pliki są wystarczająco duże, aby było to niewykonalne, to co musisz zrobić, to czytać plik w fragmentach (jeśli wzór, który chcesz zastąpić, nie obejmuje wielu linii, to jeden fragment zwykle oznacza jedną linię - możesz użyć File.foreachdo czytaj plik wiersz po wierszu), a dla każdej porcji wykonaj na nim podstawienie i dołącz go do pliku tymczasowego. Kiedy skończysz iterować plik źródłowy, zamknij go i użyj, FileUtils.mvaby zastąpić go plikiem tymczasowym.
Podoba mi się podejście do przesyłania strumieniowego. Jednocześnie mamy do czynienia z dużymi plikami, więc zwykle nie mamy miejsca w pamięci RAM, aby odczytać cały plik
Innym podejściem jest użycie edycji w miejscu w Rubim (nie z wiersza poleceń):
#!/usr/bin/rubydef inplace_edit(file, bak,&block)
old_stdout = $stdout
argf = ARGF.clone
argf.argv.replace [file]
argf.inplace_mode = bak
argf.each_line do|line|yield line
end
argf.close
$stdout = old_stdout
end
inplace_edit 'test.txt','.bak'do|line|
line = line.gsub(/search1/,"replace1")
line = line.gsub(/search2/,"replace2")
print line unless line.match(/something/)end
Jeśli nie chcesz tworzyć kopii zapasowej, zmień '.bak'na ''.
Byłoby to lepsze niż próba slurp ( read) pliku. Jest skalowalny i powinien być bardzo szybki.
Tin Man
Gdzieś jest błąd powodujący, że Ruby 2.3.0p0 w systemie Windows nie działa z odmową uprawnień, jeśli na tym samym pliku pracuje kilka kolejnych bloków inplace_edit. Aby odtworzyć testy podzielonego wyszukiwania1 i wyszukiwania2 na 2 bloki. Nie zamykasz całkowicie?
mlt
Spodziewałbym się problemów z wieloma edycjami pliku tekstowego występującymi jednocześnie. Jeśli nic innego, możesz dostać źle zniekształcony plik tekstowy.
Oto rozwiązanie umożliwiające znajdowanie / zastępowanie we wszystkich plikach w danym katalogu. Zasadniczo wziąłem odpowiedź udzieloną przez sepp2k i rozszerzyłem ją.
# First set the files to search/replace in
files =Dir.glob("/PATH/*")# Then set the variables for find/replace@original_string_or_regex=/REGEX/@replacement_string="STRING"
files.each do|file_name|
text =File.read(file_name)
replace = text.gsub!(@original_string_or_regex,@replacement_string)File.open(file_name,"w"){|file| file.puts replace }end
Bardziej pomoże, jeśli podasz wyjaśnienie, dlaczego jest to preferowane rozwiązanie i wyjaśnisz, jak to działa. Chcemy uczyć, a nie tylko dostarczać kod.
Tin Man
trollop został przemianowany na optymistę github.com/manageiq/optimist . Jest to po prostu parser opcji CLI, który nie jest naprawdę wymagany do odpowiedzi na pytanie.
noraj
1
Jeśli musisz wykonać podstawienia w granicach linii, użycie ruby -pi -enie zadziała, ponieważ pprzetwarza jedną linię na raz. Zamiast tego zalecam następujące czynności, chociaż może się to nie udać w przypadku pliku o wielu GB:
Poszukuje białych znaków (potencjalnie zawierających nowe linie), po których następuje cudzysłów, w którym to przypadku pozbywa się białych znaków. To %q(')tylko fantazyjny sposób cytowania znaku cudzysłowu.
* .txt można zastąpić innym zaznaczeniem lub niektórymi nazwami plików lub ścieżkami
podzielony, aby móc wyjaśnić, co się dzieje, ale nadal jest wykonywalny
# ARGV is an array of the arguments passed to the script.
ARGV[0..-3].each do|f|# enumerate the arguments of this script from the first to the last (-1) minus 2File.write(f,# open the argument (= filename) for writingFile.read(f)# open the argument (= filename) for reading.gsub(ARGV[-2],ARGV[-1]))# and replace all occurances of the beforelast with the last argument (string)end
EDYTUJ: jeśli chcesz użyćwyrażenia regularnego użyj tego Oczywiście jest to tylko do obsługi stosunkowo małych plików tekstowych, bez gigabajtowych potworów
Ten kod nie zadziała. Proponuję przetestować go przed wysłaniem, a następnie skopiować i wkleić działający kod.
Tin Man
@theTinMan Zawsze testuję przed publikacją, jeśli to możliwe. Przetestowałem to i działa, zarówno ta krótka, jak i komentowana wersja. Jak myślisz, dlaczego nie?
Piotr
jeśli masz na myśli użycie wyrażenia regularnego, zobacz moją edycję, również przetestowaną:>)
File.read
należy złagodzić informacjami ze stackoverflow.com/a/25189286/128421, wyjaśniającymi, dlaczego siorbanie dużych plików jest złe. Również zamiastFile.open(filename, "w") { |file| file << content }
odmian użyjFile.write(filename, content)
.Odpowiedzi:
Zastrzeżenie: To podejście jest naiwną ilustracją możliwości Rubiego, a nie rozwiązaniem do zastępowania ciągów w plikach na poziomie produkcyjnym. Jest podatny na różne scenariusze awarii, takie jak utrata danych w przypadku awarii, przerwania lub zapełnienia dysku. Ten kod nie nadaje się do niczego poza szybkim, jednorazowym skryptem, w którym wszystkie dane są archiwizowane. Z tego powodu NIE kopiuj tego kodu do swoich programów.
Oto krótki krótki sposób, aby to zrobić.
źródło
File.write(file_name, text.gsub(/regexp/, "replace")
W rzeczywistości Ruby ma funkcję edycji lokalnej. Możesz powiedzieć, jak Perl
Spowoduje to zastosowanie kodu w cudzysłowach do wszystkich plików w bieżącym katalogu, których nazwy kończą się na „.txt”. Kopie zapasowe edytowanych plików zostaną utworzone z rozszerzeniem „.bak” (chyba „foobar.txt.bak”).
UWAGA: wygląda na to, że nie działa w przypadku wyszukiwania wielowierszowego. W tym przypadku musisz zrobić to w inny mniej ładny sposób, stosując skrypt opakowujący wokół wyrażenia regularnego.
źródło
<main>': undefined method
gsub 'dla main: Object (NoMethodError)-i
edytuje w miejscu..bak
to rozszerzenie pliku kopii zapasowej (opcjonalnie).-p
jest czymś w rodzajuwhile gets; <script>; puts $_; end
. ($_
to ostatnia przeczytana linia, ale możesz przypisać do niej coś w rodzajuecho aa | ruby -p -e '$_.upcase!'
.)Pamiętaj, że kiedy to zrobisz, w systemie plików może zabraknąć miejsca i możesz utworzyć plik o zerowej długości. Jest to katastrofalne, jeśli robisz coś takiego jak wypisywanie plików / etc / passwd w ramach zarządzania konfiguracją systemu.
Zwróć uwagę, że edycja plików w miejscu, taka jak w zaakceptowanej odpowiedzi, zawsze spowoduje obcięcie pliku i sekwencyjne wypisanie nowego pliku. Zawsze wystąpi sytuacja wyścigu, w której współbieżni czytelnicy zobaczą obcięty plik. Jeśli proces zostanie przerwany z jakiegokolwiek powodu (ctrl-c, OOM killer, awaria systemu, awaria zasilania itp.) Podczas zapisu, to obcięty plik również zostanie pozostawiony, co może być katastrofalne. Jest to rodzaj scenariusza utraty danych, który programiści MUSZĄ wziąć pod uwagę, ponieważ tak się stanie. Z tego powodu uważam, że zaakceptowana odpowiedź najprawdopodobniej nie powinna być zaakceptowaną odpowiedzią. Jako minimum napisz do pliku tymczasowego i przenieś / zmień nazwę pliku na miejsce, tak jak w „prostym” rozwiązaniu na końcu tej odpowiedzi.
Musisz użyć algorytmu, który:
Odczytuje stary plik i zapisuje do nowego pliku. (Musisz uważać na wrzucanie całych plików do pamięci).
Jawnie zamyka nowy plik tymczasowy, w którym można zgłosić wyjątek, ponieważ nie można zapisać buforów plików na dysku, ponieważ nie ma miejsca. (Złap to i wyczyść plik tymczasowy, jeśli chcesz, ale musisz w tym momencie coś ponownie wrzucić lub dość mocno zawieść.
Naprawia uprawnienia do plików i tryby w nowym pliku.
Zmienia nazwę nowego pliku i umieszcza go na miejscu.
Dzięki systemom plików ext3 masz gwarancję, że metadane zapisywane w celu przeniesienia pliku na miejsce nie zostaną przestawione przez system plików i zapisane przed zapisaniem buforów danych dla nowego pliku, więc powinno to się powieść lub zakończyć niepowodzeniem. System plików ext4 również został załatany, aby obsługiwał tego typu zachowanie. Jeśli jesteś bardzo paranoikiem, powinieneś wywołać wywołanie
fdatasync()
systemowe w kroku 3.5 przed przeniesieniem pliku na miejsce.Niezależnie od języka jest to najlepsza praktyka. W językach, w których wywołanie
close()
nie zgłasza wyjątku (Perl lub C), należy jawnie sprawdzić wynikclose()
i zgłosić wyjątek, jeśli się nie powiedzie.Powyższa sugestia, aby po prostu wsypać plik do pamięci, manipulować nim i zapisać go do pliku, gwarantuje utworzenie plików o zerowej długości na pełnym systemie plików. Trzeba zawsze używać
FileUtils.mv
do poruszania się w pełni napisany plik tymczasowy na miejscu.Ostatnią kwestią jest umieszczenie pliku tymczasowego. Jeśli otworzysz plik w / tmp, musisz wziąć pod uwagę kilka problemów:
Jeśli / tmp jest zamontowany w innym systemie plików, możesz uruchomić / tmp bez miejsca przed wypisaniem pliku, który w innym przypadku byłby możliwy do wdrożenia w miejscu docelowym starego pliku.
Prawdopodobnie ważniejsze jest to, że kiedy spróbujesz
mv
przenieść plik na urządzenie, zostaniesz przekonwertowany nacp
zachowanie. Stary plik zostanie otwarty, stary i-węzeł plików zostanie zachowany i ponownie otwarty, a zawartość pliku zostanie skopiowana. Najprawdopodobniej to nie jest to, czego chcesz i możesz napotkać błąd „plik tekstowy zajęty”, jeśli spróbujesz edytować zawartość uruchomionego pliku. To również przeczy celowi używaniamv
poleceń systemu plików i możesz uruchomić docelowy system plików bez miejsca, mając tylko częściowo zapisany plik.Nie ma to również nic wspólnego z implementacją Rubiego. System
mv
icp
polecenia zachowują się podobnie.Bardziej preferowane jest otwarcie pliku tymczasowego w tym samym katalogu, w którym znajduje się stary plik. Gwarantuje to, że nie będzie problemów z przenoszeniem między urządzeniami.
mv
Sama nigdy nie uda, i zawsze należy uzyskać pełną i untruncated pliku. Podczas zapisywania pliku tymczasowego należy napotkać wszelkie awarie, takie jak brak miejsca na urządzeniu, błędy uprawnień itp.Jedyne wady podejścia do tworzenia pliku tymczasowego w katalogu docelowym to:
Oto kod, który implementuje pełny algorytm (kod systemu Windows jest nieprzetestowany i niedokończony):
A tutaj jest nieco ściślejsza wersja, która nie przejmuje się wszystkimi możliwymi przypadkami skrajnymi (jeśli używasz Uniksa i nie obchodzi Cię pisanie do / proc):
Naprawdę prosty przypadek użycia, gdy nie dbasz o uprawnienia systemu plików (albo nie pracujesz jako root, albo pracujesz jako root i plik należy do administratora):
TL; DR : Powinno to być używane zamiast zaakceptowanej odpowiedzi jako minimum we wszystkich przypadkach, aby mieć pewność, że aktualizacja jest niepodzielna, a współbieżni czytelnicy nie zobaczą obciętych plików. Jak wspomniałem powyżej, utworzenie pliku Temp w tym samym katalogu co edytowany plik jest tutaj ważne, aby uniknąć tłumaczenia operacji mv na różnych urządzeniach na operacje cp, jeśli / tmp jest zamontowany na innym urządzeniu. Wywołanie fdatasync to dodatkowa warstwa paranoi, ale spowoduje to spadek wydajności, więc pominąłem to w tym przykładzie, ponieważ nie jest powszechnie praktykowane.
źródło
Tak naprawdę nie ma sposobu na edycję plików w miejscu. To, co zwykle robisz, kiedy możesz sobie z tym poradzić (tj. Jeśli pliki nie są zbyt duże), to wczytujesz plik do pamięci (
File.read
), wykonujesz podstawienia na odczytanym ciągu (String#gsub
), a następnie zapisujesz zmieniony ciąg z powrotem do plik (File.open
,File#write
).Jeśli pliki są wystarczająco duże, aby było to niewykonalne, to co musisz zrobić, to czytać plik w fragmentach (jeśli wzór, który chcesz zastąpić, nie obejmuje wielu linii, to jeden fragment zwykle oznacza jedną linię - możesz użyć
File.foreach
do czytaj plik wiersz po wierszu), a dla każdej porcji wykonaj na nim podstawienie i dołącz go do pliku tymczasowego. Kiedy skończysz iterować plik źródłowy, zamknij go i użyj,FileUtils.mv
aby zastąpić go plikiem tymczasowym.źródło
Innym podejściem jest użycie edycji w miejscu w Rubim (nie z wiersza poleceń):
Jeśli nie chcesz tworzyć kopii zapasowej, zmień
'.bak'
na''
.źródło
read
) pliku. Jest skalowalny i powinien być bardzo szybki.To działa dla mnie:
źródło
Oto rozwiązanie umożliwiające znajdowanie / zastępowanie we wszystkich plikach w danym katalogu. Zasadniczo wziąłem odpowiedź udzieloną przez sepp2k i rozszerzyłem ją.
źródło
źródło
Jeśli musisz wykonać podstawienia w granicach linii, użycie
ruby -pi -e
nie zadziała, ponieważp
przetwarza jedną linię na raz. Zamiast tego zalecam następujące czynności, chociaż może się to nie udać w przypadku pliku o wielu GB:Poszukuje białych znaków (potencjalnie zawierających nowe linie), po których następuje cudzysłów, w którym to przypadku pozbywa się białych znaków. To
%q(')
tylko fantazyjny sposób cytowania znaku cudzysłowu.źródło
Tutaj alternatywa dla one linera od jima, tym razem w scenariuszu
Zapisz go w skrypcie, np. Replace.rb
Zaczynasz w wierszu poleceń z
* .txt można zastąpić innym zaznaczeniem lub niektórymi nazwami plików lub ścieżkami
podzielony, aby móc wyjaśnić, co się dzieje, ale nadal jest wykonywalny
EDYTUJ: jeśli chcesz użyćwyrażenia regularnego użyj tego Oczywiście jest to tylko do obsługi stosunkowo małych plików tekstowych, bez gigabajtowych potworów
źródło