我有一个包含 a、b、c、d 和 e 列的 CSV 文件,以及另一个包含 z 列的文件。在从第一个文件中逐行读取时,我只需要字段 c 和 d,同时我想将第二个文件中的 d 与 z 进行比较。
z 是一个变量,含义是for i in catfileb do ......
。现在,如果 d 与 z 相同,则显示 z,但如果它们不同,则始终显示“pin”。但如果 z 是最长或最小,则显示“lon”或“sma”。
文件一:
a b c d e
1 2 2 3 3
3 4 6 5 9
4 5 0 9 9
文件b:
z
3
1
8
所以 c、d 和 z 是变量,所以我想到了两个循环。逐行读取文件a,得到c和d,然后与z进行比较。
答案1
假设您想要将 in 中的行file b
与 in 中的相应行进行比较file a
(即两个文件具有相同的行数并且您正在逐行比较),您可以使用 Perl 脚本来为您执行此操作:
#!/usr/bin/perl
$file_a = "/path/to/file_a";
$file_b = "/path/to/file_b";
open $fa,'<',$file_a or die "Failed to open file $file_a: $!\n";
open $fb,'<',$file_b or die "Failed to open file $file_b: $!\n";
@file_a = <$fa>;
@file_b = <$fb>;
close $fa;
close $fb;
for (0..$#file_a){
($col_c,$col_d) = (split / /,$file_a[$_])[2,3];
$col_z = $file_b[$_];
$to_display = "$col_c $col_d";
if($col_z eq $col_d){
$to_display .= " $col_z";
}
else{
$to_display .= " pin";
if ($col_z gt $col_c and $col_z gt $col_d ){
$to_display .= " lon";
}
elsif($col_z lt $col_c and $col_z lt $col_d) {
$to_display .= " sma";
}
}
print "$to_display\n";
}
将上述文件另存为(将和/path/to/myscript
的位置修改为您的真实位置后),然后使其可执行:最后调用它:。file_a
file_b
chmod +x /path/to/myscript
$ /path/to/myscript
答案2
正如我在评论中所说,我不完全确定你想做什么,你似乎总是想打印字段c
并d
进行比较仅有的 d
和z
。如果是这样,下面的解决方案应该有效。
$ paste a b | awk '{print $3,$4,$6}' | head -n 1; paste a b | tail -n +2 |
while read a b c d e z; do
echo -n "$c $d";
if [ "$d" -lt "$z" ]; then
echo "pin sma";
elif [ "$d" -gt "$z" ]; then
echo "pin lon";
else echo $z;
fi;
done
运行您提供的示例文件,这给出:
c d z
2 33
6 5pin lon
0 9pin lon
解释
由于您想要进行算术比较,因此标题会破坏脚本。但是,我想您希望将它们包含在最终输出中。所以,首先我打印它们:
paste a b | awk '{print $3,$4,$6}' | head -n 1;
因此,现在我们要处理其余字段,跳过标头。所以,我们paste
再次查看文件,跳过标题 ( tail -n +2
) 并处理字段。