クエリの結果を含むElement_query
というファイルがあります。
SQL> select count (*) from element;
[Output of the query which I want to keep in my file]
SQL> spool off;
シェルコマンドで1行目と最終行を削除したい。
GNU sed
を使用:
sed -i '1d;$d' Element_query
仕組み:
-i
オプションはファイル自体を編集します。必要に応じて、そのオプションを削除し、出力を新しいファイルまたは別のコマンドにリダイレクトすることもできます。1d
は最初の行を削除します(1
は最初の行のみを操作し、d
は削除します)$d
は最後の行を削除します($
は最後の行のみを操作し、d
は削除します)さらに進む:
1,5d
は最初の5行を削除します。SQL>
を使用して、/^SQL> /d
で始まるすべての行を削除することもできます。/^$/d
で空白行をすべて削除できますstatement1;statement2;satement3;...
)で区切るか、コマンドラインで個別に指定する(-e 'statement1' -e 'statement 2' ...
)ことにより、任意のステートメントを組み合わせることができます。{ head -n[num] >/dev/null
head -n[num]
} <infile >outfile
上記を使用すると、最初のhead
コマンドを使用して出力の先頭から取り除く最初の行数と、書き込む行数outfile
を指定できます。秒で。また、通常、これはsed
よりも速く実行されます-特に入力がlargeの場合-2つの呼び出しが必要ですが。ただし、sed
は間違いなくすべきの方が望ましいですが、<infile
がnot正規の場合lseekable file-これは通常notが意図したとおりに機能するためですが、sed
はすべての出力変更を1つのスクリプトプロセスで処理できます。
GNU head
を使用すると、2番目のコマンドでも-
に[num]
の否定形を使用できます。この場合、次のコマンドは入力から最初と最後の行を削除します。
{ head -n1 >/dev/null
head -n-1
} <infile >outfile
sed
:たとえば、20行の入力を読んでいて、最初の3行と最後の7行を取り除きたいと思った場合、sed
で削除することを決意した場合、テールバッファーを使用してそれを行います。最初に3と7を足して合計ストリップ数を10にしてから、次のようにします。
seq 20 | sed -ne:n -e '3d;N;1,10bn' -eP\;D
これは、入力から最初の3行と最後の7行を取り除く例です。アイデアは、スタックのパターンスペースの入力の末尾から削除したいだけの行をバッファリングできますが、引き込まれたすべての行について、最初の行のみをP
rintします。
1,10
sed
P
rintsは何もしないので、b
ranchループの行ごとにパターンスペースに入力をスタックします。sed
のすべてのスタックがd
eletedです。そのため、最初の3行は一度に出力から削除されます。sed
が入力の$
last行に達してN
extをプルしようとすると、EOFがヒットし、処理が完全に停止します。ただし、その時点でパターンスペースには、すべての行14,20
が含まれています-P
rintedはまだありません。sed
P
rintsはパターンスペースで最初に発生する\n
ewlineまでのみであり、D
eletesは、残っているもので新しいサイクルを開始する前に同じです-または次の6行の入力。 7番目の行は、新しいサイクルでN
extコマンドを使用してスタックに再度追加されます。したがって、seq
の出力(20の連続番号の付いた行)のうち、sed
は次の出力のみを出力します。
4
5
6
7
8
9
10
11
12
13
これは、sed
のパフォーマンスがパターンスペースのサイズに直接比例するため、入力の末尾から削除する行の数が多い場合に問題になります。それでも、多くの場合、これは実行可能なソリューションです。POSIXでは、バスティングの前に少なくとも4 KBを処理するsed
パターンスペースを指定しています。
この解決策を試してください:
tail -n +2 name_of_file | head -n-1
カスタマイズ
tail
;の+2
を変更して、最初のn行を削除するように簡単に変更できます。
またはhead
の-1
を変更する最後のn行を削除します。
awk
の範囲の間の行を選択できます(これは、行の数がわかっていることを前提としています)。
awk 'NR>1 && NR < 3' file
またはPerlでは:
Perl -ne 'print if $.>1 && $.<3' file
行数がわからない場合は、grep
を使用してその場で計算できます(これは空白行をカウントしないことに注意してください。grep -c '' file
を使用してそれらもカウントします):
awk -vm="$(grep -c . file2.txt)" 'NR>1 && NR<m' file2.txt
複数の行を削除する方法についてはお答えしません。私はこの方法で問題を攻撃します:
grep -v '#SQL>' Element_query >outfile
行を数える代わりに、プロンプトを認識することでSQLコマンドを排除します。その後、このソリューションは、2つよりも多くのコマンドを含むSQLセッションの他の出力ファイルに対して一般化できます。
ed
は「標準のテキストエディター」であり、GNU sed
がないシステムで使用できます。元々はテキストエディターとして設計されていましたが、しかし、スクリプトに適しています。
printf '%s\n' 1d '$d' w q | ed Element_query
1d
はファイルの最初の行を削除します$d
(シェルが変数と見なさないように引用)は最後の行を削除し、w
はファイルを書き込み、q
はed
を終了します。 printf
は、ここでed
のコマンドをフォーマットするために使用されます-それぞれの後に改行が必要です。もちろん、これを実現する他の方法があります。
SQLコマンドを切り捨てることで、はるかに良い結果が得られます。これは、次の2つの方法で実行できます。
あなたが絶対に確信している場合シーケンス「SQL>
"は、出力の他の場所では発生しません。
grep -v -F 'SQL> ' < infile > outfile
よくわからない場合は
grep -v '^SQL> .*;$' < infile > outfile
2番目のバージョンは、速度は遅くなりますがより正確です。「SQL>」で始まりセミコロンで終わる行は無視されます。セミコロンは、削除したい行を説明しているようです。
ただし、そもそもその余分な出力をファイルに入れない方がよいでしょう。ほとんどのSQLシステムには、これを行う方法がいくつかあります。私はOracleに精通していませんが、多分 この答え が役立つかもしれません。
ファイルから先頭行と末尾行を削除するには、いくつかの方法があります。
awk
は、パターンマッチングと行カウントの両方を処理するため、使用できます。
#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};'
grep -v
を使用して、不要な行をパターンで除外できます。また、-E
オプションを使用して複数のパターンに一致させることができます。
grep -v -E "SQL>" < inputfile > outputfile
head
およびtail
を使用して、特定の行数をトリムできます。
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
vi/vim
を使用して、最初と最後の行を削除できます。
vi inputfile
:1
dd
:$
dd
:w! outputfile
:x
perlスクリプトを使用して、最初の行をスキップし、各行を保存し、次の行を取得したら印刷することができます。
#left as exercise for the reader :-)
awk
の使用:
< inputfile awk 'NR>1 {print r}; {r=$0}' > outputfile
< inputfile
:inputfile
のコンテンツをawk
のstdin
にリダイレクトします> outputfile
:awk
のコンテンツstdout
をoutputfile
にリダイレクトしますNR>1
:処理中のレコードの数が1より大きい場合にのみ、次のアクションを実行します{print r}
:変数r
の内容を出力します{r=$0}
:処理中のレコードの内容を変数r
に割り当てますしたがって、awk
スクリプトの最初の実行では、最初のアクションブロックは実行されませんが、2番目のアクションブロックが実行され、レコードの内容が変数r
に割り当てられます。 2回目の実行では、最初のアクションブロックが実行され、変数r
の内容が出力されます(前のレコードが出力されます)。これには、処理された各行を印刷する効果がありますが、最初の行と最後の行は印刷されます。