使用 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
我有一个包含数百万行的大型文本文件,我需要从中提取特定行。
因为我需要提取大约 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