我有一个非常大的文本列表,需要一种方法来提取以相同的 2 个字符开头的行,然后将这些行保存到以这 2 个字符命名的单独文件中。
示例列表:
abWEye7kgw7
abff34ZSrZf
abke8mzMyma
b2R5mPZGbCb
b2zhhCeLZzZ
b2q2T5rkACp
k9ekzbc8nUh
k9QzXBUrNT7
k92RtdXntZ3
vrTtR9GmbWG
vraVM9QXWzY
vrME9QnksBf
期望的输出:
ab* > ab.txt
b2* > b2.txt
k9* > k9.txt
vr* > vr.txt
该列表相当大,并且有很多前 2 个字符的组合。
答案1
$ awk '{ f = substr($0,1,2) ".txt"; print >f }' file.in
$ ls
ab.txt b2.txt file.in k9.txt vr.txt
$ cat ab.txt
abWEye7kgw7
abff34ZSrZf
abke8mzMyma
这显然也可以在 shell 中解决,但awk
更适合解析文本文件。挑选substr()
出输入文件中每行的前两个字符,并将其分配给f
添加.txt
到末尾的变量。会将print
当前行输出到名称为 的文件中f
。
我相信您可以取消变量并直接在之后f
使用表达式,但不能在我在 OpenBSD 上使用的实现中使用(这可能是一个错误)。substr()
>
awk
如果两个第一个字符的不同组合数量太多,则可能会遇到打开文件太多的问题。
以下变体将解决这个问题:
awk '{ f = substr($0,1,2) ".txt"; print >>f; close(f) }' file.in
答案2
awk
解决方案:
awk -v FS='' '{ print > $1$2".txt" }' file
生成的文件之一:
$ cat k9.txt
k9ekzbc8nUh
k9QzXBUrNT7
k92RtdXntZ3
答案3
尝试这个:
cat list.txt | while IFS= read -r st; do echo $st >> ${st:0:2}.txt; done
答案4
我使用下面的方法来达到结果。测试其工作正常
for j in `awk '{print substr($1,1,2)}' k.txt | uniq -c | awk '$1 >=2 {print $2}'`; do sed -n "/^$j/p" k.txt > $j.txt; done
它提取每行的前两个字符。如果前 2 个字符在多于 1 行中相同。它将打印相关行,并将这些行保存在前 2 个字符的文件名中
输出
cat ab.txt
abWEye7kgw7
abff34ZSrZf
abke8mzMyma
cat b2.txt
b2R5mPZGbCb
b2zhhCeLZzZ
b2q2T5rkACp
cat k9.txt
k9ekzbc8nUh
k9QzXBUrNT7
k92RtdXntZ3
cat vr.txt
vrTtR9GmbWG
vraVM9QXWzY
vrME9QnksBf