我有一个名为Element_query
包含查询结果的文件:
SQL> select count (*) from element;
[Output of the query which I want to keep in my file]
SQL> spool off;
我想使用shell命令删除第一行和最后一行。
我有一个名为Element_query
包含查询结果的文件:
SQL> select count (*) from element;
[Output of the query which I want to keep in my file]
SQL> spool off;
我想使用shell命令删除第一行和最后一行。
Answers:
使用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' ...
)分别指定它们来组合任何语句1,3d
将删除前三行),但结束时会有些困难。根据您的需要,最好使用this:sed -i '/^SQL> /d' Element_query
删除SQL>
以文件开头的行,而不管它在文件中的什么位置。
sed -i '1d' table-backup.sql
删除了SQL文本文件的第一行
{ head -n[num] >/dev/null
head -n[num]
} <infile >outfile
使用上面的命令,您可以指定要从输出的开头去除第一个head
命令的行的第一个行数,以及要写入outfile
第二个命令的行数。尽管需要两次调用,但它通常比sed
-特别是在输入较大时 - 更快地执行此操作。当sed
绝对应该是首选,虽然,在该情况下,<infile
是不是有规律的,lseekable文件-因为这通常不会如预期在这种情况下,但工作sed
可以处理在一个单一的,脚本化过程中所有的输出修改。
使用GNU,head
您也可以在第二个命令中使用-
否定形式[num]
。在这种情况下,以下命令将从输入中删除第一行和最后一行:
{ head -n1 >/dev/null
head -n-1
} <infile >outfile
sed
:例如,假设我正在读取20行的输入,并且想剥离前3条和最后7条。如果我决定这样sed
做,则将使用尾部缓冲区。我首先将三个和七个加在一起,得出总共十个试纸条,然后执行以下操作:
seq 20 | sed -ne:n -e '3d;N;1,10bn' -eP\;D
这是从输入中去除前3行和后7行的示例。这个想法是,您可以在堆栈的模式空间中缓冲希望从输入的尾部剥离的任意多行,但P
对于拉入的每一行,只保留第一个行。
1,10
sed
P
什么都不会漂洗,因为对于每一种,它都是在b
牧场循环中逐行地将输入堆叠在模式空间中。sed
的堆栈d
都被删除-因此前3行在一次下降中被从输出中剥离。sed
到达$
输入的最后一行并尝试拉入N
ext时,它将到达EOF并完全停止处理。但是那时模式空间包含所有行14,20
-没有行被P
漂洗过,从没有被洗掉。sed
P
上,仅\n
刷新到模式空间中第一个出现的ewline,并D
在开始新的循环之前将其删除,而剩下的就是-或接下来的6行输入。N
在新循环中,使用ext命令将第7行再次追加到堆栈中。因此,在seq
的输出(按顺序编号的20行)中,sed
仅输出:
4
5
6
7
8
9
10
11
12
13
当您希望从输入的尾部剥离的行数很大时,这将成为问题-因为sed
的性能直接与其模式空间的大小成正比。不过,在许多情况下,它仍然是可行的解决方案-POSIX规定了sed
模式空间以在破坏前至少处理4kb。
tail
还支持扩展tail -n+<num>
语法,意思是“从行开始<num>
”
我不会回答如何删除许多行。我将以这种方式解决问题:
grep -v '#SQL>' Element_query >outfile
它不用计数行,而是通过识别提示来消除SQL命令。然后,该解决方案可以推广到SQL会话的其他输出文件,而不仅仅是两个命令。
有几种方法可以从文件中删除开头和结尾行。
您可以使用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 :-)
head
s,您实际上并不需要管道,实际上,如果可以使用它,最好不要使用它。当您这样做时head | head
-虽然两个进程可以同时运行,但是它们实际上都冗余地处理了所有相同的数据。如果您改为这样做,则{ head >dump; head >save; } <in
只能跳过偏移量-第一个向读取10行,>dump
第二个向读取接下来的 10行>save
。
试试这个解决方案:
tail -n +2 name_of_file | head -n-1
客制化
您可以轻松地适应它给删除了n个第一线改变+2
的tail
;
或删除最后n行改变-1
的head
。
使用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
脚本时,不执行第一个动作块,而执行第二个动作块,并且将记录的内容分配给变量r
;在第二次执行时,将执行第一个动作块,并r
打印变量的内容(因此将打印先前的记录);这具有打印每条处理过的行(但第一行和最后一行)的效果。
r
。