При чтении из файла выберите конкретные поля и сравните их с другим файлом в Unix bash?

У меня есть файл CSV, который содержит столбцы a, b, c, d и e и другой файл, содержащий столбец z. При чтении строки за строкой из первого файла я хочу только поля c и d, и в то же время я хочу сравнить d с z из второго файла.

z – переменное значение, for i in catfileb do ...... Теперь, если d совпадает с z, тогда отобразите z, но если они разные, тогда всегда отображается «pin». Но если z – это, например, самый длинный или самый маленький дисплей «lon» или «sma».

Файл a:

 abcde 1 2 2 3 3 3 4 6 5 9 4 5 0 9 9 

Файл b:

 z 3 1 8 

Итак, c, d и z являются переменными, поэтому я думал о двух циклах. При чтении строки по строке a, get c и d, затем сравните с z.

Предполагая, что вы хотите сравнить строки в file b с соответствующими строками в 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 .

Как я уже сказал в своем комментарии, я не совсем уверен, что вы пытаетесь сделать, вы, кажется, хотите всегда печатать поля c и d и сравнивать только d с z . Если да, то решение ниже должно работать.

 $ paste ab | awk '{print $3,$4,$6}' | head -n 1; paste ab | tail -n +2 | while read abcdez; 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 

Запустите на примере файлы, которые вы предоставили, это дает:

 cdz 2 33 6 5pin lon 0 9pin lon 

объяснение

Поскольку вы хотите провести арифметическое сравнение, заголовки нарушат сценарий. Однако, я думаю, вы хотели бы иметь их в финальном выпуске. Итак, сначала я печатаю их:

 paste ab | awk '{print $3,$4,$6}' | head -n 1; 

Итак, теперь мы хотим обработать остальные поля, пропуская заголовок. Итак, мы снова paste файлы, пропускаем заголовки ( tail -n +2 ) и обрабатываем поля.