Фильтровать столбцы в строке с помощью awk, переданного с помощью xargs

Я еще не нашел прямого ответа на этот вопрос, но полагаю, что это связано с тем, что в системе используется материнская плата без -EFI.

В конце концов мне удалось установить Fedora, используя версию Netinstall, однако у меня было несколько попыток, когда система либо не загружалась с диска, либо диск был поврежден. Однако во время установки загрузчик не смог полностью установиться, я провел исследование и обнаружил, что мне пришлось переустановить GRUB2. Проблема заключалась в том, что материнская плата (и ASUS P5QL PRO )не поддерживали UEFI и, следовательно, не имели режима загрузки. Если нет способа установить Fedora без UEFI, но это совсем другое.

Вот краткий обзор:

  • Мне удалось загрузиться с большинства дисков, которые я использовал, записанных неправильно. Ошибки при записи не было, однако мой оптический привод был не в лучшем состоянии, и использование другого привода решило половину проблемы.
  • Материнская плата не поддерживала UEFI и поэтому не могла правильно установить загрузчик. Я попытался переустановить GRUB2, но в конечном итоге это не удалось.
3
28.08.2019, 12:13
2 ответа

В вашем выражении

 "cat my.log | grep @ | tail -n 1 | awk '{ print $3 }'"

...двойные -кавычки вокруг этой строки означают, что одинарные -кавычки рассматриваются как литералы. Они не защищают $3от оболочки, поэтому он расширяется как переменная среды. Поскольку $3на самом деле не определяется оболочкой (, если это не находится в сценарии, который вы вызвали с 3 аргументами ), он становится пустой строкой, а выражение awkпросто { print }, печать всей строки.

Это можно исправить, выйдя из$:

ls *.csv | xargs -I@ bash -c "cat my.log | grep @|tail -n 1|awk '{print \$3}'"

...или переместив awkиз выражения xargs:

ls *.csv | xargs -I@ bash -c "cat my.log | grep @|tail -n 1"|awk '{print $3}'
4
27.01.2020, 21:12

Направлять вывод lsв xargs— плохая идея (на самом деле, делать что-либо с выводом lsкроме простого просмотра его в терминале — плохая идея)]. Если вам абсолютно необходимо сделать что-то подобное, по крайней мере, используйте что-то вроде find. -maxdepth 1 -type f -iname '*.csv' -print0и передайте это в xargs -0r.

Но в этом случае вам вообще не нужно этого делать, потому что имена файлов.csv уже вmy.log.

В ОК:

#!/usr/bin/awk -f

{ seen[$1] = $3 }

END {
  for (f in seen) { print seen[f] };
}

или в виде одного -вкладыша:

$ awk '{seen[$1] = $3}; END {for (f in seen) { print seen[f] };}' my.log 
c
d
d

Они будут печатать последнее значение, увиденное в столбце 3, для каждого файла, указанного в столбце 1.

Если вы хотите, чтобы печаталось только первое значение из столбца 3,изменить его на:

!seen[$1] { seen[$1] = $3 }

Если вы не хотите использовать find | xargsи вам действительно нужно использовать имена файлов всех .csvфайлов, которые в настоящее время находятся в текущем каталоге, один из вариантов — сделать что-то вроде этого:

#!/usr/bin/perl

use strict;

my $logfile=shift;      # get the first arg (the logfile name)

my $re=join("|",@ARGV); # turn the remaining args into a regular expression

@ARGV=$logfile;         # set the logfile name as the sole cmd-line argument.

my %seen=();

while(<>) {
   next unless (m/^($re)/o); # ignore any filenames that weren't on the cmd line.
   my(@F) = split;
   $seen{$F[0]} = $F[2];  # perl arrays start from 0, not 1.
};

foreach my $file (sort keys %seen) {
  print $seen{$file}, "\n";
};

сохранить как, например. nandro.pl, сделайте его исполняемым с помощью chmod +xи запустите как:

$./nandro.pl my.log *.csv
c
d
d
4
27.01.2020, 21:12

Теги

Похожие вопросы