我有一个包含许多这样的行的文件
33B87401
33B87402
33B87403
33B8EE44
33B87405
33B87406
33B87407
33B87408
33B87409
33B8740A
33B8740B
33B8740C
33B87D0D
33B8740E
33B8740F
33B87410
33B87411
33B87C1E
33B87CC3
33B87C1C
我正在寻找一种方法来仅保留只有 2 个字母字符的行
这个例子的输出是
33B8740A
33B8740B
33B8740C
33B8740E
33B8740F
这是另一个列表
8765C3E3
8765C3E4
8765C3E5
8765C3E6
8765C3E7
8765C3E8
8765C3E9
8765C3EA
8765C3EB
8765C3EC
8765C3ED
8765C3EE
8765C3EF
8765C3F0
阅读许多 sed 和 awk 的示例,并且非可以重现这一点。
谢谢
答案1
sed -ne's/[[:alpha:]]//3;t' -e's//&/2p' <in >out
...将s///
替换掉[[:alpha:]]
类中任何字符在一行中第三次出现的位置。随后t
判断此替换是否成功,如果成功,则从脚本中分支出来。
因为sed
被指示-n
自动打印,所以具有三个或更多字母字符的输入行此时被有效地从输出中删除,并且第二个s///
替换语句剩下的唯一输入行是具有两个或更少字母字符的输入行。
第二个替换使用//
左侧的空正则表达式 - 对于sed
,(更有效率)指的是最近编译的/
regexp
/
- 所以可以s/[[:alpha:]]/...
再次读作。这个尝试将s///
一行中第二次出现的字母字符替换为&
自身 - 因此会导致有效的空操作并且不会对该行进行实际修改。然而,如果它可以成功地做到这一点,那么该行也会被p
打印到输出。
总之 - 第一个s///
替换有效地从输出中删除与三个或更多字母字符匹配的所有输入行,第二个替换p
会保留剩余内容以仅输出与两个字母字符匹配的输入行。
...w/ grep
...
grep -xE '([0-9]*[[:alpha:]]){2}' <in >out
该声明并不完全按照要求执行。它从输入中仅选择那些仅由字母数字组成的行,并且在该子集中仅选择那些匹配不超过或少于两个字母的行,其中第二个必须是最后一个字符。该语句将从示例输入生成示例所需的输出。
不过,要按照要求去做:
grep -xE '([^[:alpha:]]*[[:alpha:]]){2}[^[:alpha:]]*'
该语句将选择与不超过或少于两个字母字符匹配的输入行,这些字母字符可以在输入行的任何位置找到,并且可以由任意数量的^
非字母字符分隔。
grep
的-x
开关在两种情况下都使用。不过,如果^
行头锚点和$
行尾锚点分别(前置|附加)附加到正则表达式,则任何一个语句都可以不使用。该-x
开关表示一个全线匹配 - 因此正则表达式必须从头到尾完整地描述所有匹配的输入行。
答案2
我会用perl
:
perl -ne 'print if length s/\d//gr == 2'
其中使用:
-n
隐式包装while ( <> ) {
循环s///r
返回替换后的文本,但不修改原始文本。- 所以我们删除所有数字,然后查看字符串长度
- 如果是 2,则打印该行。
注意:这将从行中删除数字,留下非数字。你可以用[^A-Z]
它来代替。
或者 - 如果更清楚的话:
perl -ne 'print if (()=m/([A-Z])/g) == 2'
这适用于perl
不支持该r
标志的旧版本。它使用正则表达式匹配来选择文本,并计算数组元素(匹配)的数量。如果是 2,则打印该行。
答案3
我刚刚写了一个简单的 python 脚本,它完全符合你的要求,我在你的输入上测试了它,它工作得很好。
#!/usr/bin/python
def count_letters(input):
count=0
for char in input:
if char.isalpha():
count += 1
return count
fh=open('test_input','r')
for line in fh.readlines():
if count_letters(line) == 2 :
print line
答案4
和awk
awk '{x=$0; gsub(/[^[:alpha:]]/, "", x)};length(x) == 2' file
这会将每一行设置为一个变量,然后用空字符串x
替换其中的所有非字母字符。x
如果如此修改的长度x
等于2
,则相关行符合条件
或者,与grep
grep '^[^[:alpha:]]*[:[:alpha:]][^[:alpha:]]*[:[:alpha:]][^[:alpha:]]*$' file