Mam plik o nazwie Element_query
zawierają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_query
zawierają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 :
-i
opcja edycji samego pliku. Możesz również usunąć tę opcję i przekierować dane wyjściowe do nowego pliku lub innego polecenia, jeśli chcesz.1d
usuwa pierwszy wiersz ( 1
aby działać tylko w pierwszym wierszu, d
aby go usunąć)$d
usuwa ostatni wiersz ( $
aby działać tylko na ostatnim wierszu, d
aby go usunąć)Idąc dalej :
1,5d
usunąłby pierwsze 5 wierszy.SQL>
użycia instrukcji/^SQL> /d
/^$/d
statement1;statement2;satement3;...
) lub określając je osobno w wierszu poleceń ( -e 'statement1' -e 'statement 2' ...
)1,3d
usunie 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_query
do usuwania linii, które zaczynają się SQL>
bez względu na to, gdzie jest w pliku.
sed
liniowcem - 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 head
procesach - jest to najszybszy sposób to zrobić zwykle.
sed -i '1d' table-backup.sql
usuwał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 head
poleceniem oraz liczbę linii do zapisania outfile
za 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 sed
na pewno powinny być preferowane jest jednak to, że w przypadku <infile
jest nie regularny, lseekable plik - bo będzie to zazwyczaj nie działa prawidłowo w tym przypadku, ale sed
może obsługiwać wszystkie modyfikacje wyjściowych w jednym, skryptów procesu.
W GNU head
moż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 P
zrewidować tylko pierwszą z nich dla każdej wciągniętej linii.
1,10
sed
P
nic nie rintuje, ponieważ dla każdego z nich układa dane wejściowe w przestrzeni wzorów linia po linii w b
pętli ranch.sed
stos jest d
eletowany - a więc pierwsze 3 linie są usuwane z wyjścia za jednym zamachem.sed
osiągnie $
ostatni wiersz wejścia i spróbuje wyciągnąć N
ext, 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 P
zaznaczona i nigdy nie jest.sed
P
łączy się tylko do pierwszego występującego \n
ewline w przestrzeni wzorów i D
usuwa 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ą N
polecenia ext w nowym cyklu.I tak z seq
wyniku (który składa się z 20 kolejno ponumerowanych linii) , sed
wypisuje 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ż sed
wydajność jest wprost proporcjonalna do wielkości przestrzeni wzorcowej. Jednak w wielu przypadkach jest to realne rozwiązanie - a POSIX określa sed
przestrzeń wzorcową do obsługi co najmniej 4 kb przed zniszczeniem.
tail
obsł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.
ed
jest „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
1d
usuwa pierwszy wiersz pliku $d
(cytowany, aby powłoka nie myślała, że jest zmienną) usuwa ostatni wiersz, w
zapisuje plik i q
kończy pracę ed
. printf
sł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ć, awk
ponieważ 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 -v
aby wykluczyć linie, których nie chcesz według wzoru, i możesz dopasować wiele wzorów za pomocą -E
opcji,
grep -v -E "SQL>" < inputfile > outputfile
Możesz używać head
i tail
przycinać 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/vim
i 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, >dump
a 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 > outfile
Jeśli nie jesteś tak pewien,
grep -v '^SQL> .*;$' < infile > outfile
Druga 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 '' file
aby 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 +2
od tail
;
lub usunąć ostatnie n wierszy Zmiana -1
z head
.
Używanie awk
:
< inputfile awk 'NR>1 {print r}; {r=$0}' > outputfile
< inputfile
: Przekierowuje zawartość inputfile
do awk
„sstdin
> outputfile
: Przekierowuje treść awk
„s stdout
dooutputfile
NR>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 r
Tak więc przy pierwszym wykonaniu awk
skryptu 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 r
wypisywana jest zawartość zmiennej (tak więc drukowany jest poprzedni rekord); powoduje to wydruk każdego przetworzonego wiersza, ale pierwszego i ostatniego.
r
.