我有一个制表符分隔file
:
qrs John tuv
abcd Sam efgh
ijk Sam lmnp
abcd Sam efgh
ijk Sam lmnp
qrs John tuv
我正在尝试打印第二个字段与第二个字段中的前一行的值不匹配的行,并打印第二个字段与下一行不匹配的行。
我一直在尝试以下的变体,但没有一个像我期望的那样工作:
awk -F"\t" '{
name=$3;
line=$0;
getline;
newname=$3;
newline=$0;
getline;
nextname=$3;
nextline=$0;
if (newname != name || name != nextname)print line"\n"nextline }' input.txt
答案1
来自你评论,我假设它是一个带有登录和注销日期的日志文件,例如:
date1 John logout
date2 Sam login
date3 Sam work1
date4 Sam work2
date5 Sam logout
date6 John login
使用awk
:
awk 'NR!=1&&$2!=f{print p"\n"$0} {f=$2; p=$0}' file
在哪里:
NR!=1
awk
当处理除第一行之外的每一行时为 true (NR
包含当前文件中的行号)$2!=f
将第二个字段$2
与变量的值进行比较f
(f
稍后设置)- 如果两种配置都适用,则打印(前一行,也将稍后设置)、换行符和当前行的
awk
值。p
\n
$0
- 如果两种配置都适用,则打印(前一行,也将稍后设置)、换行符和当前行的
- 现在发生的事情是每行处理:变量
f
设置为第二个字段$2
,变量设置p
为当前行$0
。两者都将在下一次迭代中使用(当处理下一行时)。
现在打印第二个字段的第一次和最后一次出现,即注销和登录日期和名称。那么输出将是:
date1 John logout
date2 Sam login
date5 Sam logout
date6 John login
答案2
$2
通过在下面的命令中指定一个值为 try 的变量:
awk -F"\t" 'NR != 1 { if ( x != $2 ) print $0; } { x = $2 }' file