2009-08-07 4 views
8

Mam ogromny plik SQL, który zostanie wykonany na serwerze. Zrzut jest z mojego komputera i zawiera kilka ustawień dotyczących mojej maszyny. Zasadniczo chcę, aby każde wystąpienie "c://temp" zostało zastąpione przez "//home//some//blah"Polecenie Linux, aby zastąpić ciąg w pliku LARGE innym ciągiem

Jak można to zrobić z wiersza poleceń?

+0

tracisz spływu% w swojej komendzie. Jest to s% foo% bar% nie s% foo% bar –

Odpowiedz

29

sed to dobry wybór dla dużych plików.

sed -i.bak -e 's%C://temp%//home//some//blah%' large_file.sql 

Jest to dobry wybór, ponieważ nie czyta całego pliku na raz, aby go zmienić. Cytując instrukcję:

Edytor strumień służy do wykonywania podstawowe transformacje tekstowych na wejściu strumienia (plik lub wejściowego z rurociągu). Pod pewnymi względami podobne do do edytora, który pozwala na edycję skryptową (np. Ed), sed działa pod numerem , wykonując tylko jedno przejście przez dane wejściowe ( ), a zatem jest bardziej wydajne niż . Ale zdolność filtra sed do filtrowania tekstu w potoku, który szczególnie odróżnia go od innych typów edytorów od .

Odpowiednia sekcja instrukcji to here. Małe wyjaśnienie następująco

-i.bak umożliwia montaż w miejsce pozostawiania kopii zapasowej z rozszerzeniem .bak

s%% foo bar% używa s, polecenie podstawienia, które zamienniki mecze pierwszego ciągu pomiędzy znakiem%, "foo", dla drugiego ciągu znaków , "pasek". Zwykle jest napisany jako // , ale ponieważ twoje struny mają dużo ukośników, wygodniej jest zmienić je na coś innego, abyś unikał ich ucieczki.

Przykład

 
[email protected]:~$ sed -i.bak -e 's%C://temp%//home//some//blah%' a.txt 
[email protected]:~$ more a.txt 
//home//some//blah 
D://temp 
//home//some//blah 
D://temp 
[email protected]:~$ more a.txt.bak 
C://temp 
D://temp 
C://temp 
D://temp 
+2

Możesz użyć innego znaku, aby uniknąć konieczności cytowania ukośników, na przykład sed -e "s% C: // temp%/home // some // blah% ". Również opcja -i pozwala na zapisanie pliku w miejscu, gdy jesteś pewien opcji. – dalloliogm

+0

To jest polecenie, które piszę: sed -i.bak-e% C: \\ temp \%/home/liveon/public_html/tmp 'liveon.sql i to jest błąd uzyskanie: sed: -e expression # 1, char 41: unterminated 's 'command Ktoś? – coderama

+0

Brakuje ostatniego%, polecenie jest s% foo% bar% –

1

Polecenie sed może zrobić. Zamiast ucieczki ukośniki, można wybrać inny ogranicznik (_ w tym przypadku):

sed -e 's_c://temp/_/home//some//blah/_' file1.txt > file2.txt 
+0

Tęskniłeś za ostatnim podkreśleniem: "s_c: // temp/_/home // some // blah_" – dalloliogm

+0

dzięki! Zostało to naprawione. – stefanw

4

Spróbuj sed? Coś w rodzaju:

sed 's/c:\/\/temp/\/\/home\/\/some\/\/blah/' mydump.sql > fixeddump.sql 

Ucieczka z tych wszystkich ukośników sprawia, że ​​wygląda to okropnie, oto prosty przykład, który zmienia foo na bar.

sed 's/foo/bar/' mydump.sql > fixeddump.sql 

jak inni to zauważyli, można wybrać swój własny separator, który uniemożliwiłby leaning toothpick syndrome w tym przypadku:

sed 's|c://temp\\|home//some//blah|' mydump.sql > fixeddump.sql 

Pomysłowa rzeczą sed jest to, że działa na strumienia raczej niż plik naraz, dzięki czemu możesz przetwarzać ogromne pliki, używając tylko niewielkiej ilości pamięci.

+0

Dziękuję Paul! Intellij Idea staje się szalony i robi to przez dziesiątki minut, podczas gdy z sed zajmuje 1 sekundę, aby zastąpić ukośnik odwrotny z podwójnym odwróconym ukośnikiem w moim pliku sql. – gumkins

12

Tylko dla kompletności. Zastępowanie miejsca za pomocą perl.

perl -i -p -e 's{c://temp}{//home//some//blah}g' mysql.dmp 

Nie są wymagane również żadne odwrotne ukośniki. ;)

+10

Zwróć uwagę, że jeśli użyjesz flagi '-i' bez rozszerzenia, otrzymasz * no backup *. Jeśli chcesz utworzyć kopię zapasową, wypróbuj '-i.bak', który wykona edycję lokalną * i * da kopię zapasową oryginału jako' original.bak', prawie za darmo. – Telemachus

+0

Pozwoliłem, aby mój system kontroli wersji obsługiwał tworzenie kopii zapasowych. – jrockway

+3

@Jrockway: To jest dla ciebie piękne, ale zakładam, że pliki, o których mowa, są pod kontrolą wersji i że wiesz, co robi -i.bak i nie zdecydowałeś się go użyć. Chciałbym tylko, żeby ludzie, którzy zalecają zmianę -i, potrzebowali dwóch sekund, aby wyjaśnić różnicę między -i i -i.bak. Naprawdę będzie bolało, jeśli pliki, z którymi grasz, nie są pod kontrolą wersji i zrobisz prostą literówkę (np. Zapomnij o opcji -p). – Telemachus

3

Istnieje również niestandardowe narzędzie UNIX, rpl, które robi dokładnie to samo, co przykłady sed; jednak nie jestem pewien, czy rpl działa strumieniowo, więc sed może być lepszą opcją tutaj.

+0

Heh, za przypadkiem, jesteś przyjacielem programisty rpl?:-) –

+0

Nie, nigdy nie słyszałem o facecie z zewnątrz; przydało się do zrobienia zadania zamiany wsadowej na kilka tysięcy plików tekstowych i trzymałem je w moim zestawie narzędzi. –

+0

Warto powiedzieć: * dlaczego * polecasz w tym przypadku (lub dlaczego możesz, ponieważ w połowie odbierasz rekomendację). Oznacza to, że zamiast podawać nazwę narzędzia, powiedz nam, co Ci się podobało. – Telemachus

1
perl -pi -e 's#c://temp#//home//some//blah#g' yourfilename 

-p będzie traktować ten skrypt jako pętla będzie czytać określonego pliku linia po linii biegnącej regex wyszukiwania i zamiany.

-i Ta flaga powinna być używana w połączeniu z opcją -p. To polecenie Perl do edycji pliku na miejscu.

-e Po prostu oznacza wykonanie tego kodu perl.

Powodzenia

+0

dziękuję za wyjaśnienie –

1

gawk

awk '{gsub("c://temp","//home//some//blah")}1' file