我有一个~23000行的SQL转储,其中包含几个数据库的数据价值。我需要提取这个文件的某个部分(即单个数据库的数据),并将其放在一个新文件中。我知道我想要的数据的开始行号和结束行号。

谁知道一个Unix命令(或一系列命令)可以从文件中提取16224到16482行之间的所有行,然后将它们重定向到一个新文件中?


当前回答

我编写了一个小型bash脚本,您可以从命令行运行它,只要您更新PATH以包含它的目录(或者您可以将它放在PATH中已经包含的目录中)。

用法:$ pinch filename起始行结束行

#!/bin/bash
# Display line number ranges of a file to the terminal.
# Usage: $ pinch filename start-line end-line
# By Evan J. Coon

FILENAME=$1
START=$2
END=$3

ERROR="[PINCH ERROR]"

# Check that the number of arguments is 3
if [ $# -lt 3 ]; then
    echo "$ERROR Need three arguments: Filename Start-line End-line"
    exit 1
fi

# Check that the file exists.
if [ ! -f "$FILENAME" ]; then
    echo -e "$ERROR File does not exist. \n\t$FILENAME"
    exit 1
fi

# Check that start-line is not greater than end-line
if [ "$START" -gt "$END" ]; then
    echo -e "$ERROR Start line is greater than End line."
    exit 1
fi

# Check that start-line is positive.
if [ "$START" -lt 0 ]; then
    echo -e "$ERROR Start line is less than 0."
    exit 1
fi

# Check that end-line is positive.
if [ "$END" -lt 0 ]; then
    echo -e "$ERROR End line is less than 0."
    exit 1
fi

NUMOFLINES=$(wc -l < "$FILENAME")

# Check that end-line is not greater than the number of lines in the file.
if [ "$END" -gt "$NUMOFLINES" ]; then
    echo -e "$ERROR End line is greater than number of lines in file."
    exit 1
fi

# The distance from the end of the file to end-line
ENDDIFF=$(( NUMOFLINES - END ))

# For larger files, this will run more quickly. If the distance from the
# end of the file to the end-line is less than the distance from the
# start of the file to the start-line, then start pinching from the
# bottom as opposed to the top.
if [ "$START" -lt "$ENDDIFF" ]; then
    < "$FILENAME" head -n $END | tail -n +$START
else
    < "$FILENAME" tail -n +$START | head -n $(( END-START+1 ))
fi

# Success
exit 0

其他回答

我正准备发布头部/尾部技巧,但实际上我可能只是启动emacs。: -)

Esc-x goto-line ret 16224 马克(ctrl-space) Esc-x goto-line ret 16482 esc-w

打开新的输出文件ctl-y 保存

让我看看发生了什么。

那些想要计算头部、|、尾部组合的间隔的人是想多了。

下面是如何在不计算任何东西的情况下得到“16224 - 16482”范围:

cat file | head -n +16482 | tail -n +16224

解释:

The + instructs the head/tail command to "go up to / start from" (respectively) the specified line number as counted from the beginning of the file. Similarly, a - instructs them to "go up to / start from" (respectively) the specified line number as counted from the end of the file The solution shown above simply uses head first, to 'keep everything up to the top number', and then tail second, to 'keep everything from the bottom number upwards', thus defining our range of interest (with no need to compute an interval).

cat dump.txt | head -16224 | tail -258

应该能行。这种方法的缺点是,您需要做算术来确定tail的参数,并考虑是否希望“between”包含结束行。

sed -n '16224,16482 p' orig-data-file > new-file

其中16224、16482是起始行号和结束行号,包括。这是1索引。-n抑制将输入回显为输出,这显然不是你想要的;数字表示要执行以下命令的行范围;命令p输出相关的行。

这可能为你工作(GNU sed):

sed -ne '16224,16482w newfile' -e '16482q' file

或者利用bash:

sed -n $'16224,16482w newfile\n16482q' file