所以这是家庭作业,但我不会问具体的家庭作业问题。
我需要使用 head 和 tail 从一个文件中获取不同的行集。所以像第 6-11 行和第 19-24 行一样,将它们都保存到另一个文件中。我知道我可以使用 append 来做到这一点,例如
head -11 file|tail -6 > file1; head -24 file| tail -6 >> file1.
Run Code Online (Sandbox Code Playgroud)
但我认为我们不应该这样做。
有没有一种特定的方法可以组合 head 和 tail 命令然后保存到文件中?
don*_*sti 13
head
如果您{ ... ; }
使用类似的构造对命令进行分组,则可以使用单独的基本算术来完成
{ head -n ...; head -n ...; ...; } < input_file > output_file
Run Code Online (Sandbox Code Playgroud)
其中所有命令共享相同的输入(感谢@mikeserv)。
获取第 6-11 行和第 19-24 行等效于:
head -n 5 >/dev/null # dump the first 5 lines to `/dev/null` then
head -n 6 # print the next 6 lines (i.e. from 6 to 11) then
head -n 7 >/dev/null # dump the next 7 lines to `/dev/null` ( from 12 to 18)
head -n 6 # then print the next 6 lines (19 up to 24)
Run Code Online (Sandbox Code Playgroud)
所以,基本上,你会运行:
{ head -n 5 >/dev/null; head -n 6; head -n 7 >/dev/null; head -n 6; } < input_file > output_file
Run Code Online (Sandbox Code Playgroud)
您可以使用{ … }
分组构造将重定向运算符应用于复合命令。
{ head -n 11 file | tail -n 6; head -n 24 file | tail -n 6; } >file1
Run Code Online (Sandbox Code Playgroud)
您可以跳过前 M 行并复制下 N 行,而不是复制前 M+N 行并仅保留最后 N 行。这在大文件上明显更快。请注意,+N
of的参数tail
不是要跳过的行数,而是加一 - 它是从 1 开始打印的第一行的编号。
{ tail -n +6 file | head -n 6; tail -n +19 file | head -n 6; } >file1
Run Code Online (Sandbox Code Playgroud)
无论哪种方式,输出文件只打开一次,但输入文件被遍历一次以提取每个片段。如何对输入进行分组?
{ tail -n +6 | head -n 6; tail -n +14 | head -n 6; } <file >file1
Run Code Online (Sandbox Code Playgroud)
一般来说,这是行不通的。(它可能适用于某些系统,至少当输入是常规文件时。)为什么?由于输入缓冲。大多数程序,包括tail
,不会逐字节读取输入,而是一次读取几千字节,因为它更快。所以tail
读取几千字节,在开始时跳过一点,再传递一点到head
,然后停止——但是读取的内容是读取的,不能用于下一个命令。
另一种方法是使用head
piped /dev/null
to 跳过行。
{ head -n 5 >/dev/null; head -n 6; head -n 7 >/dev/null; head -n 6; } <file >file1
Run Code Online (Sandbox Code Playgroud)
同样,由于缓冲,这不能保证工作。head
当输入来自常规文件时,它恰好与来自 GNU coreutils的命令(在非嵌入式 Linux 系统上找到的那个)一起使用。这是因为一旦这个实现head
读取了它想要的内容,它就会将文件位置设置为它没有输出的第一个字节。如果输入是管道,这将不起作用。
从文件中打印多个行序列的更简单方法是调用更通用的工具,例如sed或awk。(这可能会更慢,但它只对非常大的文件很重要。)
sed -n -e '6,11p' -e '19,24p' <file >file1
sed -e '1,5d' -e '12,18d' -e '24q' <file >file1
awk '6<=NR && NR<=11 || 19<=NR && NR<=24' <file >file1
awk 'NR==6, NR==11; NR==19, NR==24' <file >file1
Run Code Online (Sandbox Code Playgroud)