使用 sed 从大文本文件中提取多行,同时保留每个尾随换行符(Bash 脚本)

Extract multiple lines from large text file with sed while preserving each trailing newline (Bash Script)

我有一个包含数百万行的大型文本文件,我需要从中提取特定行。

因为我需要提取大约 300000 行(要提取的行号是从文件中读取的),我以 x 行(比如 200)批处理它们以使用以下命令加快处理速度:

sed '1000p;1002p;2003p;...(200 times)...10001q;d' large_text_file >> extracted.txt

首先我构造字符串 1000p;1002p;2003p;...(200 times)...10001q;d,然后我调用 sed 命令并将该字符串作为参数并重复此操作直到处理完所有行。

 sed_lines="1000p;1002p;2003p;...(200 times)...10001q;d"
 sed "$sed_lines" large_text_file >> extracted.txt

我遇到的问题是这 200 行现在被视为一行,因为 sed 没有在每行的末尾保留 \n

问题 1: sed 中是否有保留每行末尾的 \n 的选项?

答案 1:好吧,我写完这篇文章后很快就想通了 post。基本上我错过了行中 $sentences 周围的双引号 :

echo $sentences >> $forig.pseudo ==> echo "$sentences" >> $forig.pseudo

问题 2:有更快的方法吗?

回答2:fedorqui用awk的回答真的是又快又高效

为了便于理解,这里是执行此过程的大部分脚本(根据 fedorqui 的评论编辑):

echo "Extracting lines"
sed_lines=""
while IFS=$'\t' read -r linenr rest; do
        sed_lines+="$linenr"                   # Append line number
        ((cnt++))                              # Batch counter
        if [ "$cnt" -eq 200 ]; then
                sed_lines+="q;d"               
                sentences=$(sed "$sed_lines" $forig)   # Extract lines from file
                ((thres_cnt+=100))
                echo "$thres_cnt lines processed"
                echo $sentences >> $forig.pseudo       # Write lines to new file
                sed_lines=""
                cnt=0
        else
                sed_lines+="p;"
        fi
done < "$fperp"_cut_sorted

为此使用 awk 怎么样?首先将行号存储在一个数组中,然后继续检查文件的行号是否在该数组中:

awk 'FNR==NR{line[[=10=]]=[=10=]; next} FNR in line' line_numbers file

样本

$ cat line_numbers
8
16
4
6
9
$ cat file
1 hello
2 hello
3 hello
4 hello
5 hello
6 hello
7 hello
8 hello
9 hello
10 hello
11 hello
12 hello
13 hello
14 hello
15 hello
16 hello
17 hello
18 hello
19 hello
20 hello
$ awk 'FNR==NR{line[[=11=]]=[=11=]; next} FNR in line' line_numbers file 
4 hello
6 hello
8 hello
9 hello
16 hello