我有一个输入文件,例如:
a=1 b=2 c=3 d=4
a=2 b=3
a=0 c=7
a=3 b=9 c=0 d=5
a=4 d=1
c=9
假设列名(a,b,c和d)的顺序保持不变。如何编写脚本/命令来帮助我提取特定于列b和d的值?所以我的输出应该是:
b=2 d=4
b=3
b=9 d=5
d=1
我可以使用多个分隔符来编写一个“不那么好”的awk命令,使用管道来过滤这些分隔符以使用-F选项,但我相信还有更优雅的方法来执行此操作。
请帮助。
答案 0 :(得分:5)
sed 's/[^bd]=[0-9]* *//g'
答案 1 :(得分:3)
perl -pe 's/[^bd]=\d+ *//g' data_file
答案 2 :(得分:3)
# awk '{ for(i=1;i<=NF;i++){if($i~/(b|d)=/){printf $i" "} }print ""}' file
b=2 d=4
b=3
b=9 d=5
d=1
答案 3 :(得分:2)
以下是单行版本:
$ perl -lpe '@x=/([bd]=[0-9])/g; $_="@x"' test.txt列表上下文中的
m//g
将所有匹配作为列表返回。
#!/usr/bin/perl
use strict; use warnings;
while ( <DATA> ) {
if( my @cols = /([bd]=[0-9])/g ) {
print "@cols";
}
print "\n";
}
__DATA__
a=1 b=2 c=3 d=4
a=2 b=3
a=0 c=7
a=3 b=9 c=0 d=5
a=4 d=1
c=9
输出:
C:\Temp> t.pl b=2 d=4 b=3 b=9 d=5 d=1
答案 4 :(得分:1)
Sed会做得非常好:
sed -e 's/[^bd]=[^ ]*//g' -e 's/^ *//' -e 's/ *$//' < filename
第一个正则表达式清除了不需要的字段(除了b和d之外的所有字符),所以如果你改变主意,那就是修改它的地方。另外两个删除前导和尾随空格。
答案 5 :(得分:1)
在Ruby中:
#!/usr/bin/env ruby
filename = ARGV[0]
fields = ARGV[1..ARGV.length]
File.open(filename) do |file|
file.each_line do |line|
pairs = line.split(' ').map { |expression| expression.split('=') }
value_hash = Hash[pairs]
requested_fields = []
fields.each do |field|
requested_fields << "#{field}=#{value_hash[field]}" unless value_hash[field].nil?
end
puts requested_fields.join(' ')
end
end
使用ruby ruby_script_name.rb input_file.txt field1 field2
拨打电话。
我喜欢sed
/ perl
解决方案的简短程度 - 但是如何轻松修改它以获取更长的字段名称?好像正则表达式会很快变得混乱......无论如何,如果你想使用它,那么这个策略也适用于此。
答案 6 :(得分:1)
假设您可能希望将来对某些值进行操作,除了过滤之外,您可以将其作为基础。
#! /usr/bin/env perl
use warnings;
use strict;
my @lines;
while(<>){
my %kv = /([a-z])=([0-9])/ig;
push @lines, \%kv;
}
for my $kv (@lines){
# $kv->{a} ||= 1;
# next unless $kv->{c};
print "b=$kv->{b} " if defined $kv->{b};
print "b=$kv->{d} " if defined $kv->{d};
print "\n";
}
答案 7 :(得分:0)
显然,PostScript是最好的选择...... XD
(%stdin) (r) file
{
dup 100 string readline not {exit} if
{
dup () eq {pop exit} if
token pop 3 string cvs
dup 0 get << 98 / 100 / >> exch known
{print ( ) print} {pop} ifelse
} loop
/ =
} loop
用法:gs -q -dNOPROMPT -dNODISPLAY -dBATCH thisfile.ps < input
注意:将<< 98 / 100 / >>
替换为适当的ASCII值(98 = b,100 = d),每个值后跟一个以空格分隔的斜杠(尽管您不必使用斜杠;它只是一个虚拟对象)。例如,要选择“c”,“e”和“f”,请使用<< 99 / 101 / 102 / >>
每行最多100个字符;如果你的行更长,请用更大的数字替换100 string
。同样,如果您的3 string
条目超过三个字符,请替换x=#
。但是,如果x不止一个字符,则不起作用。