Natknąłem się na pytanie (na samym SO), w którym OP musi dokonać edycji i zapisać operację w samych plikach wejściowych.
Wiem, że dla jednego pliku wejściowego możemy wykonać następujące czynności:
awk '{print "test here..new line for saving.."}' Input_file > temp && mv temp Input_file
Powiedzmy teraz, że musimy wprowadzić zmiany w tym samym formacie plików (załóżmy tutaj .txt).
Co próbowałem / pomyślałem o tym problemie: jego podejście polega na przechodzeniu przez pętlę for plików .txt i wywoływanie singlaawk
jest bolesnym i NIE zalecanym procesem, ponieważ marnuje zbędne cykle procesora, a dla większej liczby plików byłoby więcej powolny.
Co więc można zrobić tutaj, aby przeprowadzić edycję w miejscu dla wielu plików z NON GNU, awk
który nie obsługuje opcji inplace. Przeszedłem również przez ten wątek. Zapisz modyfikacje za pomocą awk, ale nic nie ma na imadło NON GNU awk i zmiana wielu plików w awk
sobie, ponieważ awk inny niż GNU nie ma inplace
takiej opcji.
UWAGA: Dlaczegobash
dodaję znacznik, ponieważ w części z odpowiedziami użyłem poleceń bash, aby zmienić nazwy plików tymczasowych na ich rzeczywiste nazwy pliku_wejściowego, więc dodając go.
EDYCJA: Zgodnie z komentarzem Eda, dodając tutaj przykładowy przykład, cel kodu tego wątku może być również użyty do ogólnej edycji w miejscu.
Przykładowe pliki wejściowe:
cat test1.txt
onetwo three
tets testtest
cat test2.txt
onetwo three
tets testtest
cat test3.txt
onetwo three
tets testtest
Próbka oczekiwanej wydajności:
cat test1.txt
1
2
cat test2.txt
1
2
cat test3.txt
1
2
awk
(być może w podpowłoce) lub{...}
zamkniętej grupy, a następnie zapisać wyniki w pożądanym pliku wyjściowym (dla każdego pliku wejściowego, lub połączony plik dla wszystkich plików wejściowych). Następnie przekierowujesz dane wyjściowe grupy otoczki lub grupy nawiasów klamrowych do bieżącego pliku, w którym jest zapisywany? Zwykłe dołączenie ciągu plików wejściowych poawk
poleceniu przetworzyłoby kolejno wszystkie pliki (lub coś podobnego)?awk {..} file1 .. fileX
zapisem zmodyfikowanego pliku, ponieważ np.temp01
W następnej iteracji podczas przetwarzania następnego pliku użyj a,mv -f tmp01 input01
aby zastąpić plik wejściowy zmodyfikowanymi danymi; lub (2) po prostu napisz nowy katalog./tmp/tmp01 ... ./tmp/tmp0X
podczas wykonywaniaawk
skryptu i kontynuuj z pętlą nad plikami w./tmp
katalogu i np.mv -f "$i" "input_${i##*[^0-9]}"
(lub jakimkolwiek rozszerzeniem potrzebnym do zastąpienia starych plików wejściowych.awk
pełnego uzupełnienia kodu, druga opcja jest prawie taka sama, jak używam w mojej sugestii, będzie bądź wdzięczny, jeśli mógłbyś przekazać swoje myśli na temat tego rozwiązania.Odpowiedzi:
Ponieważ głównym celem tego wątku jest to, jak zrobić w miejscu SAVE w NON GNU,
awk
dlatego publikuję najpierw jego szablon, który pomoże każdemu w dowolnym wymaganiu, należy dodać / dołączyćBEGIN
iEND
sekcję w kodzie, zachowując główny BLOK zgodnie z ich wymagania i powinien dokonać edycji w miejscu, a następnie:UWAGA: Poniższy zapisuje wszystkie dane wyjściowe do pliku_wyjściowego, więc jeśli chcesz coś wydrukować na standardowe wyjście, dodaj tylko
print...
instrukcję bez> (out)
następującego.Ogólny szablon:
Konkretne dostarczone rozwiązanie próbki:
awk
Wymyśliłem następujące podejście w sobie (dla dodanych próbek poniżej jest moje podejście do rozwiązania tego i zapisania danych wyjściowych w samym pliku_pliku_wejściowego)UWAGA: jest to tylko test zapisywania edytowanych danych wyjściowych w samym pliku (plikach) Input_file, można użyć sekcji BEGIN wraz z sekcją END w swoim programie, sekcja główna powinna odpowiadać wymaganiom konkretnego pytania.
Uczciwe ostrzeżenie: Również dlatego, że takie podejście tworzy nowy tymczasowy plik wyjściowy na ścieżce, więc lepiej upewnij się, że mamy wystarczającą ilość miejsca w systemach, chociaż w ostatecznym wyniku zachowa tylko główne pliki wejściowe, ale podczas operacji potrzebuje miejsca w katalogu system /
Poniżej znajduje się test powyższego kodu.
Wykonanie programu na przykładzie: Załóżmy, że są następujące
.txt
pliki wejściowe:Teraz, gdy uruchamiamy następujący kod:
UWAGA:
ls -lhtr
Wsystem
sekcji celowomam miejsce,aby zobaczyć, które pliki wyjściowe tworzy (tymczasowo), ponieważ później zmieni ich nazwy na swoje rzeczywiste nazwy.Kiedy wykonamy skrypt
ls -lhtr
poawk
uruchomieniu, możemy zobaczyć tylko.txt
pliki.Objaśnienie: Dodanie tutaj szczegółowego wyjaśnienia powyższego polecenia:
źródło
FNR==1
bloku, nadal możesz zapisać zmiany w miejscu. Jakawk 'FNR==1{system("rm " FILENAME)} {print "new lines" > FILENAME}' files...
. Nie jest to wcale wiarygodne (najprawdopodobniej nastąpi całkowita utrata danych), ale nadal działa w większości dobrze: DPrawdopodobnie wybrałbym coś takiego, gdybym spróbował to zrobić:
Wolałbym najpierw skopiować oryginalny plik do kopii zapasowej, a następnie wykonać operację zapisywania zmian w oryginale, ale spowodowałoby to zmianę wartości zmiennej FILENAME dla każdego niepożądanego pliku wejściowego.
Zauważ, że jeśli posiadasz oryginalne pliki o nazwie
whatever.bak
lubwhatever.new
w katalogu, zastąpisz je plikami tymczasowymi, więc musisz również dodać test. Wywołanie wmktemp
celu uzyskania nazw plików tymczasowych byłoby bardziej niezawodne.FAR bardziej użyteczną rzeczą, jaką można mieć w tej sytuacji, byłoby narzędzie, które wykonuje dowolne inne polecenie i wykonuje część edycji „inplace”, ponieważ można jej użyć do edycji „inplace” dla POSIX sed, awk, grep, tr, cokolwiek i nie wymagałoby zmiany składni skryptu na
print > out
itp. za każdym razem, gdy chcesz wydrukować wartość. Prosty, delikatny przykład:którego użyjesz w następujący sposób:
Jednym oczywistym problemem związanym z tym
inedit
skryptem jest trudność z identyfikacją plików wejściowych / wyjściowych oddzielnie od polecenia, gdy masz wiele plików wejściowych. Powyższy skrypt zakłada, że wszystkie pliki wejściowe pojawiają się jako lista na końcu polecenia, a polecenie jest uruchamiane przeciwko nim pojedynczo, ale oczywiście oznacza to, że nie można go używać do skryptów, które wymagają 2 lub więcej plików na czas, np .:lub skrypty ustawiające zmienne między plikami na liście arg, np .:
Uczynienie go bardziej solidnym jako ćwiczenie dla czytelnika, ale spójrz na
xargs
streszczenie jako punkt wyjścia do tego, jak solidnyinedit
musiałby działać :-).źródło
Rozwiązanie powłoki jest proste i prawdopodobnie wystarczająco szybkie:
Poszukaj innego rozwiązania tylko wtedy, gdy ostatecznie wykazałeś, że jest to zbyt wolne. Pamiętaj: przedwczesna optymalizacja jest źródłem wszelkiego zła.
źródło