Prawdopodobnie najlepiej jest to naprawić wewnątrz SQL * Plus; zamiast generować plik, a następnie próbować przycinać rzeczy, których nie chcesz, możesz po prostu powiedzieć SQL * Plus, aby nie generował tych rzeczy na początek. Jedno podejście opisano w sekcji „Tworzenie pliku płaskiego” na docs.oracle.com/cd/A84870_01/doc/sqlplus.816/a75664/ch44.htm ; inne podejście opisano na stronie stackoverflow.com/q/2299375/978917 .
ruakh
Odpowiedzi:
48
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 :
Możesz także usunąć zakres. Na przykład 1,5dusunąłby pierwsze 5 wierszy.
Możesz także usunąć każdą linię, która zaczyna się od SQL>użycia instrukcji/^SQL> /d
Możesz usunąć każdą pustą linię za pomocą /^$/d
Na koniec możesz połączyć dowolną instrukcję, oddzielając ją średnikiem ( statement1;statement2;satement3;...) lub określając je osobno w wierszu poleceń ( -e 'statement1' -e 'statement 2' ...)
Jeśli jego trzecia linia do usunięcia ... to muszę użyć 3d zamiast 1d? jeśli jego trzeci wiersz od ostatniego do usunięcia ... to jakie będzie polecenie?
pmaipmui
Jak usunąć trzeci wiersz z ostatniego przy użyciu poleceń powłoki?
pmaipmui
@Nainita Możesz określić zakres ( 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.
user43791,
@Nainita - zapoznaj się z moją odpowiedzią na temat arbitralnego zliczania ogonów - oferuje dwa rozwiązania usuwania linii zliczania względem końca pliku. Jeden jest 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.
mikeserv
Kiedyś sed -i '1d' table-backup.sqlusuwałem pierwszy wiersz pliku tekstowego sql
David Thomas
8
głowa; głowa
{ 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
LUB z POSIX 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.
Na liniach 1,10sedPnic nie rintuje, ponieważ dla każdego z nich układa dane wejściowe w przestrzeni wzorów linia po linii w bpętli ranch.
W trzeciej linii cały sedstos jest deletowany - a więc pierwsze 3 linie są usuwane z wyjścia za jednym zamachem.
Kiedy 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.
Co drugi wiersz sedPłą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:
45678910111213
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.
GNU tailobsługuje również rozszerzoną tail -n+<num>składnię oznaczającą „start od linii <num>”
UloPe
4
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.
Lubię to. Nie wiem dużo o SQL - ale czy nie ma szans, że monity pojawią się na początku linii wyjściowych?
mikeserv
4
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,
Dla tych 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.
mikeserv
3
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.
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 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.
Odpowiedzi:
Za pomocą GNU
sed
: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' ...
)źródło
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óchhead
procesach - jest to najszybszy sposób to zrobić zwykle.sed -i '1d' table-backup.sql
usuwałem pierwszy wiersz pliku tekstowego sqlgłowa; głowa
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 zapisaniaoutfile
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ń. Gdziesed
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, alesed
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:LUB z POSIX
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: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 wb
pętli ranch.sed
stos jestd
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 linie14,20
- z których żadna nie została jeszczeP
zaznaczona i nigdy nie jest.sed
P
łączy się tylko do pierwszego występującego\n
ewline w przestrzeni wzorów iD
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: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ślased
przestrzeń wzorcową do obsługi co najmniej 4 kb przed zniszczeniem.źródło
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.
źródło
ed
jest „standardowym edytorem tekstu” i powinien być dostępny w systemach, które nie mają GNUsed
. Został pierwotnie zaprojektowany jako edytor tekstu, ale dobrze nadaje się do pisania skryptów.1d
usuwa pierwszy wiersz pliku$d
(cytowany, aby powłoka nie myślała, że jest zmienną) usuwa ostatni wiersz,w
zapisuje plik iq
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.źródło
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,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,Możesz używać
head
itail
przycinać określoną liczbę linii,Możesz użyć
vi/vim
i usunąć pierwszą i ostatnią linię,możesz użyć skryptu perla, pominąć pierwszy wiersz, zapisać każdy wiersz, wydrukować, gdy pojawi się następny wiersz,
źródło
head
, których tak naprawdę nie potrzebujesz, i w rzeczywistości lepiej nie używać go, jeśli możesz uciec. Gdy to zrobiszhead | 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,Jeśli nie jesteś tak pewien,
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.
źródło
Możesz wybrać linie między zakresem w
awk
(zakłada się, że wiesz, ile jest linii):Lub w Perlu:
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ć):źródło
Wypróbuj to rozwiązanie:
Dostosowywanie
Można łatwo dostosować go usunąć n pierwsze linie zmieniając
+2
odtail
;lub usunąć ostatnie n wierszy Zmiana
-1
zhead
.źródło
Używanie
awk
:< inputfile
: Przekierowuje zawartośćinputfile
doawk
„sstdin
> outputfile
: Przekierowuje treśćawk
„sstdout
dooutputfile
NR>1
: wykonuje następujące działania tylko wtedy, gdy liczba przetwarzanego rekordu jest większa niż 1{print r}
: drukuje zawartość zmiennejr
{r=$0}
: przypisuje zawartość przetwarzanego rekordu do zmiennejr
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 zmiennejr
; przy drugim wykonaniu wykonywany jest pierwszy blok akcji ir
wypisywana jest zawartość zmiennej (tak więc drukowany jest poprzedni rekord); powoduje to wydruk każdego przetworzonego wiersza, ale pierwszego i ostatniego.źródło
r
.