запускать команды внутри awk перед печатью

Я хочу перечислять каталоги при расчете их размера и печатать все в простой команде, используя ls и awk , отлично справляется с управлением списком и тем, что я хочу отображать:

ls -AlhF /usr | awk '{print $6, $7, $8, "\011", $9 }'

Но я хотел бы пойти немного дальше, чтобы получить размер папок или файлов, используйте $ 9 с командой du -s с чем-то вроде этого:

ls -AlhF /usr | awk '{print $6, $7, $8, "\011", $9, du -s /usr/$9 }'

Я пробовал много способов написать его, с backticks, doublequote, но я всегда получаю ошибки или нежелательные результаты.

3 Solutions collect form web for “запускать команды внутри awk перед печатью”

Чтобы ответить на вопрос и проигнорировать вопросы о разборе вывода ls на данный момент, чтобы получить вывод (stdout) команды в awk , выполните следующие действия:

 cmd="that command" output="" while ((cmd | getline line) > 0) output = output line RS status = close(cmd) 

Как состояние выхода закодировано в переменной состояния, варьируется от одной реализации awk к другому. Все, на что вы можете положиться, это то, что он будет равен 0, если и только если cmd успешно cmd .

getline запускает оболочку (обычно это оболочка POSIX, но в некоторых системах, которая может быть оболочкой Bourne) для синтаксического анализа этой командной строки. Поэтому важно правильно указывать данные там. Лучше всего использовать одинарные кавычки, которые являются самыми безопасными.

Здесь, так как выход будет одной строкой в ​​любом случае (ваш подход не может обрабатывать имена файлов с любыми символами пробела, не говоря уже о символах новой строки), вам нужно всего лишь сделать один getline :

  awk -vq="'" ' function shquote(s) { gsub(q, q "\\" qq, s) return qsq } { cmd = "du -sk " shquote("/usr/" $9) cmd | getline du_output status = close(cmd) }' 

Если вы вызываете getline без имени переменной, то она устанавливает $0 что упрощает извлечение дискового пространства:

 DIR=/usr export DIR LC_ALL=C ls -l -- "$DIR" | awk -vq="'" ' function shquote(s) { gsub(q, q "\\" qq, s) return qsq } { date = $6 " " $7 " " $8 name = $9 cmd = "du -sk " shquote(ENVIRON["DIR"] (ENVIRON["DIR"] ~ /^\/*$/ ? "" : "/") name) cmd | getline disk_usage = $1 print date "\t" name "\t" disk_usage }' 

Вот реализация perl которая не зависит от разбора вывода ls -l (который по своей сути ненадежен) и может быть легко изменен для использования любого формата вывода даты или формата.

Сохраните его в файл, сделайте его исполняемым и запустите его как /path/to/script /usr . Для сценария требуется один или несколько аргументов имени каталога.

 #!/usr/bin/perl use strict; use Date::Format; if ($#ARGV < 0) { die "Missing directory argument" }; foreach my $dir (@ARGV) { $dir =~ s:/+$::; # strip trailing / opendir(my $dh, $dir) || die "Can't opendir $dir: $!"; while (readdir $dh) { next if (m/^\.{1,2}$/); # skip . and .. entries my $mtime=(stat("$dir/$_"))[9]; # extract mtime field from stat my $mtime_f = time2str('%Y-%m-%d %X', $mtime); open(my $fh, "-|", 'du', '-s', '--', "$dir/$_"); my $du = <$fh>; ($du) = split(' ',$du); # only want the first blank-separated field close($fh). printf "%s\t%s\t%s\n", $mtime_f, "$dir/$_" , $du; } closedir $dh; }; 

Есть более простые и более короткие способы сделать это (в perl или awk или на других языках), но это дает полезную базу для сообщения другой информации о каталогах и их содержимом. см. perldoc -f stat для получения полной информации об информации, доступной из функции stat() .

BTW, это может быть реализовано в awk , но вам придется реализовать свою собственную функцию stat() и функцию форматирования даты. Легче использовать perl .

GNU awk aka gawk поддерживает загружаемые модули, а модуль filefuncs предоставляет stat() который заполняет массив statdata[] . Используйте, добавив @load "filefuncs" в верхней части вашего awk скрипта.

 ls -AlhF /usr | awk '{print "echo "$6" "$7" "$8" \011 "$9" $(du -s /usr/"$9")" }' | sh 

Постройте эхо и команду du с awk, а затем выполните ее через трубопровод sh.

  • Добавить mth и nth столбцы файла со столбцами другого файла
  • Как умножить два столбца в awk?
  • Что такое массив в awk?
  • Сравнение двух файлов с использованием awk-языка
  • суммирование двух матриц, каждый из которых в другом файле
  • Как объединить файлы CSV
  • сортировать и uniq в awk
  • Как отсортировать поток данных по двум именам столбцов (номер столбца может отличаться)?
  • Удалить строку, содержащую первое появление «pattern1» после последнего появления «pattern2»?
  • фильтровать данные по значению столбца
  • Выходные линии между двумя датами параметров ВКЛЮЧАЯ первую дату параметра, но не вторую
  • Linux и Unix - лучшая ОС в мире.