我想知道如何使用grep以显示以相同字符开头和结尾的所有行。
我想知道如何使用grep以显示以相同字符开头和结尾的所有行。
Answers:
POSIXly:
pattern='\(.\).*\1
.'
grep -x -- "$pattern" file
如果行以无效的字节字符开始或结束行将不起作用,如果要覆盖这种情况,可以添加LC_ALL=C,尽管仅LC_ALL=C适用于单字节字符数据。
perl6 如果您将其放在包装盒中,它似乎是最好的工具:
$ printf '\ue7\u301 blah \u107\u327\n121\n1\n123\n' |
perl6 -ne '.say if m/^(.).*$0$/ || /^.$/'
ḉ blah ḉ
121
1
虽然它仍然会使无效字符窒息。
请注意,这perl6将通过将其变成NFC表格来更改您的文本:
$ printf '\u0044\u0323\u0307\n' |
perl6 -pe '' |
perl -CI -ne 'printf "U+%04x\n", ord for split //'
U+1e0c
U+0307
U+000a
$ printf '\u0044\u0323\u0307\n' |
perl -pe '' |
perl -CI -ne 'printf "U+%04x\n", ord for split //'
U+0044
U+0323
U+0307
U+000a
在内部,perl6以NFG形式(代表Normalization Form Grapheme)存储字符串,这是perl6一种可以正确处理未组合字素的发明方式:
$ printf '\u0044\u0323\u0307\n' | perl6 -ne '.chars.say'
1
$ printf '\u0044\u0323\u0307\n' | perl6 -ne '.codes.say'
2
perl6尽管如此会改变文本(将其转换为NFC(归一化形式为“ composed”(归一化)形式))。
perl6存储,这是正确处理未组合字素的一种方式。NFGGGraphemeperl6
不是grep而是awk:
awk -F "" 'NF && $1 == $NF'
处理以下特殊情况:
空的FS会将记录拆分为gawk,mawk和中的每个字段一个字符busybox awk(字节,不是后两个字符),但这不是标准的,并且在awkA,W和K的原始字段派生的实现中不起作用在BSD和Universe商业上。更便于携带,但需要输入:
awk '/./ && substr($0,1,1) == substr($0,length)'
FS由于空字符串不是标准的,因此在某些awk实现中将不起作用。
awk 'length&&substr($0,1,1)==substr($0,length)'length$0{print $0}
nawk几乎一样糟糕:-)
grep -xe '\(.\).*\1' -e .
例:
$ printf '%s\n' il y était cet été | grep -xe '\(.\).*\1' -e .
y
été
-x用于完全匹配(整行匹配)。\1是对中捕获的字符的后向引用\(.\)。我们添加a -e .来照顾包含一个字符的行的特殊情况。
假定输入内容在当前语言环境中包含有效文本。
匹配是在字符上,而不是字节上(不是UTF-8中的é是两个字节0xc3 0xa9),也不是graphem簇(如果这些é以其分解形式写成,e然后是U + 0301,则不起作用)例如结合重音符号)。
要使用grep支持-PPCRE的石墨烯簇进行工作:
$ printf 'e\u0301te\u0301\n' | grep -xPe '(\X).*\1|\X'
été
假定两个簇的分解是相同的,例如a ḉ表示为c U+0301 U+0327将与a c U+0327 U+0301或ć(U+0107)U+0327或ç(U+00E7)U+0301或ḉ(U+1E09)表示的不匹配。为此,您需要对标准化表格进行检查:
$ printf '\ue7\u301 blah \u107\u327\n' |
perl -MUnicode::Normalize -C -ne '
print if /^\X$/ || NFC($_) =~ /^(\X).*\1$/'
ḉ blah ḉ
perl6,perl6 -ne '.say if m/^(.).*$0$/ || /^.$/'则应为您完成所有工作。
快速python2替代:
python -c 'import sys;[sys.stdout.write(l) for l in sys.stdin if len(l)>1 and l.rstrip("\n").endswith(l[0])]' < input.txt
例:
$ python -c 'import sys;[sys.stdout.write(l) for l in sys.stdin if len(l)>1 and l.rstrip("\n").endswith(l[0])]' < input.txt | cat -A
nathan$
ookie $
a line a$