Answers:
sed
发布此问题后不久,我就得出了答案。sed
到目前为止,没有人使用过:
sed '$!N;/^\(.*\)\n\1$/d;P;D'
稍作处理较一般的问题(删除三行或四行或五行中的行该怎么办?)提供了以下可扩展的解决方案:
sed -e ':top' -e '$!{/\n/!{N;b top' -e '};};/^\(.*\)\n\1$/d;P;D' temp
扩展以删除三行:
sed -e ':top' -e '$!{/\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1$/d;P;D' temp
或删除四边形:
sed -e ':top' -e '$!{/\n.*\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1\n\1$/d;P;D' temp
sed
与大多数其他选项相比,它还有一个额外的优势,那就是它能够真正在流中运行,所需的存储空间不超过要检查重复项的实际行数。
正如cuonglm在评论中指出的那样,必须将语言环境设置为C,以避免无法正确删除包含多字节字符的行。因此,以上命令变为:
LC_ALL=C sed '$!N;/^\(.*\)\n\1$/d;P;D' temp
LC_ALL=C sed -e ':top' -e '$!{/\n/!{N;b top' -e '};};/^\(.*\)\n\1$/d;P;D' temp
LC_ALL=C sed -e ':top' -e '$!{/\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1$/d;P;D' temp
# Etc.
它不是很优雅,但是很简单:
uniq -c input | awk '{if ($1 % 2 == 1) { print substr($0, 9) }}'
substr()只是修剪uniq
输出。直到行的重复项超过9,999,999(在这种情况下,uniq的输出可能会溢出9个字符),这才起作用。
uniq -c input | awk '{if ($1 %2 == 1) { print $2 } }'
,它似乎同样有效。有什么理由substr
版本更好?
$2
以$NF
使其更健壮?
foo bar
。
据我了解,我使用每个记录的哈希选择awk的问题,在这种情况下,我假设RS = \ n,但是可以将其更改为考虑任何其他类型的安排,也可以将其考虑为带有参数或小对话框的代表次数为偶数,而不是奇数。每行都用作哈希,其行数增加,在文件末尾,对数组进行扫描并打印记录的每个偶数。我包括计数以进行检查,但是,删除a [x]足以解决该问题。
高温超导
计数线代码
#!/usr/bin/nawk -f
{a[$0]++}
END{for (x in a) if (a[x]%2!=0) print x,a[x] }
样本数据:
a
One Sunny Day
a
a
b
my best friend
my best friend
b
c
c
c
One Sunny Day
c
d
my best friend
my best friend
d
d
d
One Sunny Day
d
e
x
k
j
my best friend
my best friend
样品运行:
countlines feed.txt
j 1
k 1
x 1
a 3
One Sunny Day 3
d 5
e 1
awk
代码,但是不幸的是,awk
关联数组根本没有排序,也不保留顺序。
sort
。
!=0
是如何awk
将数字转换为真/假值所隐含的,这使其可简化为awk '{a[$0]++}END{for(x in a)if(a[x]%2)print x}'
使用外壳结构
uniq -c file | while read a b; do if (( $a & 1 == 1 )); then echo $b; fi done
$b
)而中断。
有趣的难题!
在Perl中:
#! /usr/bin/env perl
use strict;
use warnings;
my $prev;
while (<>) {
$prev = $_, next unless defined $prev; # prime the pump
if ($prev ne $_) {
print $prev;
$prev = $_; # first half of a new pair
}
else {
undef $prev; # discard and unprime the pump
}
}
print $prev if defined $prev; # possible trailing odd line
详细地在Haskell中:
main :: IO ()
main = interact removePairs
where removePairs = unlines . go . lines
go [] = []
go [a] = [a]
go (a:b:rest)
| a == b = go rest
| otherwise = a : go (b:rest)
在Haskell中:
import Data.List (group)
main = interact $ unlines . map head . filter (odd . length) . group . lines
一个版本:我使用“定界符”来简化内部循环(它假定第一行不是__unlikely_beginning__
,并且假定文本不是以line:结尾__unlikely_ending__
,并在输入行的末尾添加该特殊定界符。算法可以同时假设:)
{ cat INPUTFILE_or_just_- ; echo "__unlikely_ending__" ; } | awk '
BEGIN {mem="__unlikely_beginning__"; occured=0; }
($0 == mem) { occured++ ; next }
( occured%2 ) { print mem ;}
{ mem=$0; occured=1; }
'
所以:
C
,否则在多字节语言环境中,该语言环境中的无效字符会导致命令失败。