我想知道如何使用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
存储,这是正确处理未组合字素的一种方式。NFG
G
Grapheme
perl6
不是grep而是awk:
awk -F "" 'NF && $1 == $NF'
处理以下特殊情况:
空的FS会将记录拆分为gawk
,mawk
和中的每个字段一个字符busybox
awk
(字节,不是后两个字符),但这不是标准的,并且在awk
A,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
支持-P
PCRE的石墨烯簇进行工作:
$ 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$