Mam plik o nazwie Element_queryzawierający wynik zapytania:
SQL> select count (*) from element;
[Output of the query which I want to keep in my file]
SQL> spool off;
Chcę usunąć 1. linię i ostatnią linię za pomocą polecenia powłoki.
Mam plik o nazwie Element_queryzawierający wynik zapytania:
SQL> select count (*) from element;
[Output of the query which I want to keep in my file]
SQL> spool off;
Chcę usunąć 1. linię i ostatnią linię za pomocą polecenia powłoki.
Odpowiedzi:
Za pomocą GNU sed:
sed -i '1d;$d' Element_query
Jak to działa :
-iopcja edycji samego pliku. Możesz również usunąć tę opcję i przekierować dane wyjściowe do nowego pliku lub innego polecenia, jeśli chcesz.1dusuwa pierwszy wiersz ( 1aby działać tylko w pierwszym wierszu, daby go usunąć)$dusuwa ostatni wiersz ( $aby działać tylko na ostatnim wierszu, daby go usunąć)Idąc dalej :
1,5dusunąłby pierwsze 5 wierszy.SQL>użycia instrukcji/^SQL> /d/^$/dstatement1;statement2;satement3;...) lub określając je osobno w wierszu poleceń ( -e 'statement1' -e 'statement 2' ...)1,3dusunie pierwsze trzy linie), ale na koniec jest to trochę trudniejsze. W zależności od tego, co chcesz, lepiej byłoby użyć tego: sed -i '/^SQL> /d' Element_querydo usuwania linii, które zaczynają się SQL> bez względu na to, gdzie jest w pliku.
sedliniowcem - który będzie działał do usuwania dowolnych liczb wierszy z początku i końca pliku. Lepiej jednak, dopóki dane wejściowe są zwykłymi plikami, to tylko zgrupowanie pojedynczych danych wejściowych w dwóch headprocesach - jest to najszybszy sposób to zrobić zwykle.
sed -i '1d' table-backup.sqlusuwałem pierwszy wiersz pliku tekstowego sql
{ head -n[num] >/dev/null
head -n[num]
} <infile >outfile
Za pomocą powyższego można określić pierwszą liczbę linii do usunięcia z nagłówka wyjścia z pierwszym headpoleceniem oraz liczbę linii do zapisania outfileza pomocą drugiego. Zazwyczaj robi to również szybciej niż sed- zwłaszcza gdy dane wejściowe są duże - pomimo konieczności dwóch wywołań. Gdzie sedna pewno powinny być preferowane jest jednak to, że w przypadku <infilejest nie regularny, lseekable plik - bo będzie to zazwyczaj nie działa prawidłowo w tym przypadku, ale sedmoże obsługiwać wszystkie modyfikacje wyjściowych w jednym, skryptów procesu.
W GNU headmożesz również użyć -formy ujemnej dla [num]drugiego polecenia. W takim przypadku następujące polecenie usunie pierwszy i ostatni wiersz z danych wejściowych:
{ head -n1 >/dev/null
head -n-1
} <infile >outfile
sed:Powiedzmy na przykład, że czytałem 20 linii i chciałem usunąć pierwsze 3 i ostatnie 7. Gdybym zdecydował się to zrobić w / sed, zrobiłbym to z buforem ogona. Najpierw dodam trzy i siedem dla całkowitej liczby pasków wynoszącą dziesięć, a następnie:
seq 20 | sed -ne:n -e '3d;N;1,10bn' -eP\;D
To przykład, który usuwa pierwsze 3 i ostatnie 7 wierszy z wejścia. Chodzi o to, że możesz buforować tyle wierszy, ile chcesz usunąć z końca tekstu wejściowego w przestrzeni wzoru na stosie, ale Pzrewidować tylko pierwszą z nich dla każdej wciągniętej linii.
1,10 sed Pnic nie rintuje, ponieważ dla każdego z nich układa dane wejściowe w przestrzeni wzorów linia po linii w bpętli ranch.sedstos jest deletowany - a więc pierwsze 3 linie są usuwane z wyjścia za jednym zamachem.sedosiągnie $ostatni wiersz wejścia i spróbuje wyciągnąć Next, uderza EOF i całkowicie przestaje przetwarzać. Ale w tym czasie przestrzeń wzorów zawiera wszystkie linie 14,20- z których żadna nie została jeszcze Pzaznaczona i nigdy nie jest.sed Płączy się tylko do pierwszego występującego \newline w przestrzeni wzorów i Dusuwa go przed rozpoczęciem nowego cyklu z pozostałymi - lub następnymi 6 liniami wprowadzania. Siódma linia jest ponownie dołączana do stosu za pomocą Npolecenia ext w nowym cyklu.I tak z seqwyniku (który składa się z 20 kolejno ponumerowanych linii) , sedwypisuje tylko:
4
5
6
7
8
9
10
11
12
13
Staje się to problematyczne, gdy liczba linii, które chcesz usunąć z ogona wejściowego, jest duża - ponieważ sedwydajność jest wprost proporcjonalna do wielkości przestrzeni wzorcowej. Jednak w wielu przypadkach jest to realne rozwiązanie - a POSIX określa sedprzestrzeń wzorcową do obsługi co najmniej 4 kb przed zniszczeniem.
tailobsługuje również rozszerzoną tail -n+<num>składnię oznaczającą „start od linii <num>”
Nie zamierzam odpowiadać, jak usunąć pewną liczbę wierszy. Zamierzam zaatakować problem w ten sposób:
grep -v '#SQL>' Element_query >outfile
Zamiast zliczać wiersze, eliminuje polecenia SQL, rozpoznając monity. To rozwiązanie można następnie uogólnić na inne pliki wyjściowe sesji SQL z większą liczbą poleceń niż tylko dwie.
edjest „standardowym edytorem tekstu” i powinien być dostępny w systemach, które nie mają GNU sed. Został pierwotnie zaprojektowany jako edytor tekstu, ale dobrze nadaje się do pisania skryptów.
printf '%s\n' 1d '$d' w q | ed Element_query
1dusuwa pierwszy wiersz pliku $d(cytowany, aby powłoka nie myślała, że jest zmienną) usuwa ostatni wiersz, wzapisuje plik i qkończy pracę ed. printfsłuży tutaj do formatowania poleceń ed- po każdej z nich musi znajdować się nowa linia; istnieją oczywiście inne sposoby osiągnięcia tego celu.
Istnieje kilka sposobów usuwania linii wiodących i końcowych z pliku.
Możesz użyć, awkponieważ obsługuje zarówno dopasowywanie wzorów, jak i liczenie linii,
#you need to know length to skip last line, assume we have 100 lines
awk 'NR>1 && NR<100 {print $0};' < inputfile
#or
awk '/SQL/ {next}; {print $0;};' < inputfile |awk 'NR>1&& NR<10 {print $0};'
Możesz użyć, grep -vaby wykluczyć linie, których nie chcesz według wzoru, i możesz dopasować wiele wzorów za pomocą -Eopcji,
grep -v -E "SQL>" < inputfile > outputfile
Możesz używać headi tailprzycinać określoną liczbę linii,
lines=$((`wc -l < inputfile`-2)) #how many lines in file, less 2
head -n-1 < inputfile | head -n$lines > outputfile
#or
tail -n+2 < inputfile | head -n$lines > outputfile
Możesz użyć vi/vimi usunąć pierwszą i ostatnią linię,
vi inputfile
:1
dd
:$
dd
:w! outputfile
:x
możesz użyć skryptu perla, pominąć pierwszy wiersz, zapisać każdy wiersz, wydrukować, gdy pojawi się następny wiersz,
#left as exercise for the reader :-)
head, których tak naprawdę nie potrzebujesz, i w rzeczywistości lepiej nie używać go, jeśli możesz uciec. Gdy to zrobisz head | head- oba procesy mogą działać równolegle, oba przetwarzają również praktycznie wszystkie te same dane nadmiarowo. Jeśli to zrobisz { head >dump; head >save; } <in, pomiń tylko przesunięcie - pierwszy odczytuje 10 linii do, >dumpa drugi odczytuje kolejne 10 linii do >save.
Lepiej byłoby ci służyć, odcinając polecenia SQL. Możesz to zrobić na dwa sposoby:
Jeśli masz absolutną pewność, że sekwencja „ SQL>” nie występuje nigdzie indziej w danych wyjściowych,
grep -v -F 'SQL> ' < infile > outfileJeśli nie jesteś tak pewien,
grep -v '^SQL> .*;$' < infile > outfileDruga wersja jest wolniejsza, ale dokładniejsza: zignoruje linie dokładnie zaczynające się od „SQL>” i kończące się średnikiem, które wydają się opisywać linie, które chcesz wyeliminować.
Jednak lepiej byłoby nie umieszczać tego dodatkowego wyjścia w pliku na początek. Większość systemów SQL ma na to sposób. Nie znam się zbyt dobrze na Oracle, ale może ta odpowiedź może być pomocna.
Możesz wybrać linie między zakresem w awk(zakłada się, że wiesz, ile jest linii):
awk 'NR>1 && NR < 3' file
Lub w Perlu:
perl -ne 'print if $.>1 && $.<3' file
Jeśli nie wiesz, ile jest linii, możesz obliczyć je w locie, używając grep(nie liczą się puste linie, użyj również, grep -c '' fileaby je policzyć):
awk -vm="$(grep -c . file2.txt)" 'NR>1 && NR<m' file2.txt
Wypróbuj to rozwiązanie:
tail -n +2 name_of_file | head -n-1
Dostosowywanie
Można łatwo dostosować go usunąć n pierwsze linie zmieniając +2od tail;
lub usunąć ostatnie n wierszy Zmiana -1z head.
Używanie awk:
< inputfile awk 'NR>1 {print r}; {r=$0}' > outputfile
< inputfile: Przekierowuje zawartość inputfiledo awk„sstdin> outputfile: Przekierowuje treść awk„s stdoutdooutputfileNR>1: wykonuje następujące działania tylko wtedy, gdy liczba przetwarzanego rekordu jest większa niż 1{print r}: drukuje zawartość zmiennej r{r=$0}: przypisuje zawartość przetwarzanego rekordu do zmiennej rTak więc przy pierwszym wykonaniu awkskryptu pierwszy blok akcji nie jest wykonywany, podczas gdy drugi blok akcji jest wykonywany, a zawartość rekordu jest przypisywana do zmiennej r; przy drugim wykonaniu wykonywany jest pierwszy blok akcji i rwypisywana jest zawartość zmiennej (tak więc drukowany jest poprzedni rekord); powoduje to wydruk każdego przetworzonego wiersza, ale pierwszego i ostatniego.
r.