我有一个~23000行的SQL转储,其中包含几个数据库的数据价值。我需要提取这个文件的某个部分(即单个数据库的数据),并将其放在一个新文件中。我知道我想要的数据的开始行号和结束行号。
谁知道一个Unix命令(或一系列命令)可以从文件中提取16224到16482行之间的所有行,然后将它们重定向到一个新文件中?
我有一个~23000行的SQL转储,其中包含几个数据库的数据价值。我需要提取这个文件的某个部分(即单个数据库的数据),并将其放在一个新文件中。我知道我想要的数据的开始行号和结束行号。
谁知道一个Unix命令(或一系列命令)可以从文件中提取16224到16482行之间的所有行,然后将它们重定向到一个新文件中?
当前回答
在这种情况下,您可以使用sed命令,它非常快。
如前所述,让我们假设范围是:在16224和16482行之间
#get the lines from 16224 to 16482 and prints the values into filename.txt file
sed -n '16224 ,16482p' file.txt > filename.txt
#Additional Info to showcase other possible scenarios:
#get the 16224 th line and writes the value to filename.txt
sed -n '16224p' file.txt > filename.txt
#get the 16224 and 16300 line values only and write to filename.txt.
sed -n '16224p;16300p;' file.txt > filename.txt
其他回答
站在拳击手的肩膀上,我喜欢这样:
sed -n '<first line>,$p;<last line>q' input
e.g.
sed -n '16224,$p;16482q' input
$表示“最后一行”,因此第一个命令使sed打印从第16224行开始的所有行,第二个命令使sed在打印第16428行之后退出。(在boxxar的解决方案中,为q范围添加1似乎没有必要。)
我喜欢这个变体,因为我不需要两次指定结束行号。而且我认为使用$不会对性能产生不利影响。
cat dump.txt | head -16224 | tail -258
应该能行。这种方法的缺点是,您需要做算术来确定tail的参数,并考虑是否希望“between”包含结束行。
我一直在寻找这个问题的答案,但最终我不得不编写自己的代码。以上的答案都不令人满意。 假设您有一个非常大的文件,并且有一些想要打印的行号,但这些行号不是按顺序排列的。您可以执行以下操作:
我的文件比较大 对于{a..k};执行echo $letter;完成| cat -n > myfile.txt
1 a
2 b
3 c
4 d
5 e
6 f
7 g
8 h
9 i
10 j
11 k
我想要的具体行号: shuf -i 1-11 -n 4 > line_numbers_I_want.txt
10
11
4
9
要打印这些行号,请执行以下操作。 awk ` {system("head myfile.txt -n " $0 " | tail -n 1")} ` line_numbers_I_want.txt
上面所做的是头n行,然后采取最后一行使用尾巴
如果您希望行号按顺序排列,首先sort (is -n numeric sort),然后获取行。
cat line_numbers_I_want.txt | sort -n | awk '{system("head myfile.txt -n " $0 " | tail -n 1")}'
4 d
9 i
10 j
11 k
又快又脏:
head -16428 < file.in | tail -259 > file.out
可能不是最好的方法,但应该有用。
顺便说一下:259 = 16482-16224+1。
我编写了一个小型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