Linux:使用特定字符串搜索特定列并在屏幕上打印

时间:2014-06-25 11:10:47

标签: perl bash awk sed

它的日常记录,下面的示例,虽然值格式不会改变,但记录的字段/列的位置不断变化,这在使用awk,sed,grep时会产生问题。

Filename.txt - 包含数百万条记录

abcd D20140624 Useragent username userid 
abcd D20140625 Useragent username1 userid1
D20140626 Useragent username2 userid2

结果应为:

D20140624 username userid
D20140625 username1 userid1
D20140626 username2 userid2 

如果我使用cat Filename.txt|awk -f ' ' '{print $2,$4,$5}' - 结果无效

同样sed会产生无效结果。

任何人都可以帮助我。

7 个答案:

答案 0 :(得分:1)

您可以使用awk

执行此操作
awk '!/^D20[0-9][0-9]/ {$1="";sub(/^ /,"")}1'
D20140624 Useragent username userid
D20140625 Useragent username1 userid1
D20140626 Useragent username2 userid2

如果第一个字段dos没有以一年开头,请删除它并删除多余的空间。

答案 1 :(得分:1)

使用它:

awk '{ if(NF==5) print $2,$4,$5; else print $1,$3,$4; }'

答案 2 :(得分:0)

awk '{for(i=1;i<=NF;i++)if($i~/^D[0-9]{8}$/){n=i;break}}
     {print $n,$(NF-1),$NF}' file

给出:

D20140624 username userid
D20140625 username1 userid1
D20140626 username2 userid2

它搜索匹配D....的第一列,无论它在哪里,打印它和最后两列。你没有详细说明规则,所以我带来了这个。

答案 3 :(得分:0)

您也可以使用sed命令

sed -r 's/.*(D[0-9]+) \w+ (.*)/\1 \2/g' file_name

答案 4 :(得分:0)

通过GNU sed,

$ sed -r 's/^.*(D\S*).*(usern\S*).*(useri\S*).*/\1 \2 \3/g' file
D20140624 username userid
D20140625 username1 userid1
D20140626 username2 userid2

答案 5 :(得分:0)

-f是告诉awk从文件中读取其脚本的参数,因此当您说“无效结果”时,我假设您收到错误消息can't open source file ' '

我认为您可能尝试使用-F,但' '是默认的FS值,因此无需明确设置。

一旦你遇到了这个问题,从输入文件获得你想要的输出就是:

$ awk '{print $(NF-3), $(NF-1), $NF}' file
D20140624 username userid
D20140625 username1 userid1
D20140626 username2 userid2

答案 6 :(得分:0)

使用perl one-liner,使用字段末尾的索引:

perl -lane 'print "@F[-4,-2,-1]"' file

或者使用更明确的逻辑:

perl -lane 'print @F == 5 ? "@F[1,3,4]" : "@F[0,2,3]"' file

说明:

切换

  • -l:启用行结束处理,指定行终止符
  • -a:拆分空间线并将其加载到数组@F
  • -n:为输入文件中的每个“行”创建一个while(<>){..}循环。
  • -e:告诉perl在命令行上执行代码。