Сортировка вывода с помощью awk и его форматирование - PullRequest
2 голосов
/ 06 декабря 2009

Я пытаюсь отформатировать вывод ls -la, чтобы он содержал только файлы, измененные в декабре, и выводил их красиво, вот как они сейчас выглядят:

ls -la | awk {'print $6,$7,$8,$9,$10'} | grep "Dec" | sort -r | head -5
Dec 4 20:15 folder/
Dec 4 19:51 ./
Dec 4 17:42 Folder\ John/
Dec 4 16:19 Homework\ MAT\ 08/
Dec 4 16:05 Folder\ Smith/

и т.д ..

Как я могу настроить что-то вроде регулярного выражения, чтобы не включать такие вещи, как "./" и "../",

Также, как я могу опустить косую черту "\" для папок с пробелами в них. Я хотел бы бросить косую черту в конце. Это возможно с помощью команды оболочки? Или мне придется использовать Perl для внесения изменений в тест? Я хочу, чтобы дата и время оставались как есть. Любая помощь будет принята с благодарностью!

В коробке установлен linux, и это делается через SSH.

Edit:

Вот что у меня есть (спасибо Марку и Гбэкону за это)

ls -laF | grep -vE ' ..?/?$' | awk '{ for (i=6; i<=NF; i++) printf("%s ", $i); printf("\n"); } ' | grep "Dec" | sort -r | head -5

У меня просто проблемы с заменой "\" просто пробелом "". Кроме этого Спасибо за всю помощь до этого момента!

Ответы [ 7 ]

1 голос
/ 06 декабря 2009

Вы можете использовать find для выполнения большей части работы за вас:

find -mindepth 1 -maxdepth 1 -printf "%Tb %Td %TH:%TM %f\n" | grep "^Dec" | sort -r

Родительский каталог (..) не включен по умолчанию. -mindepth 1 избавляет от текущего каталога (.). Вы можете удалить -maxdepth 1, чтобы сделать его рекурсивным, но вы должны изменить %f на %p, чтобы включить путь с именем файла.

Это поля в -printf:

  • % Tb - короткое название месяца
  • % Td - день месяца
  • % TM:% TM - часы и минуты
  • % f - имя файла

В grep я добавил совпадение для начала строки, чтобы оно не совпадало с файлом с именем «Десятичный», который был изменен, например, в ноябре.

1 голос
/ 06 декабря 2009

что со всеми грепами и сидами ???

ls -laF | awk '!/\.\.\/$/ && !/\.\/$/ &&/Dec/ { for (i=6; i<=NF; i++) printf("%s ", $i); printf("\n"); }'
1 голос
/ 06 декабря 2009

Вы можете отфильтровать вывод ls:

ls -la | grep -vE ' ..?/?$' | awk {'print $6,$7,$8,$9,$10'} | grep "Dec" | sort -r | head -5

Если вы согласны использовать Perl:

ls -la | perl -lane 's/\\ / /g;
                     print "@F[5..9]"
                       if $F[8] !~ m!^..?/?$! &&
                          $F[5] eq "Dec"'
1 голос
/ 06 декабря 2009

Проверьте и убедитесь, что ваша команда 'ls' не привязана ни к чему другому. Как правило, «raw» ls не дает вам каталоги / for и не должен выходить из пробелов.

Очевидно, что-то ускользает от пробелов для того, чтобы ваш awk печатал эти файлы, поскольку awk имеет тенденцию разбивать поле на пробелы, для этого и нужны символы \.

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

1 голос
/ 06 декабря 2009

Вот один из ваших ответов:

Как я могу настроить что-то вроде регулярного выражения, чтобы не включать такие вещи, как "./" и "../",

Используйте ls -lA вместо ls -la.

Вместо того, чтобы печатать фиксированное количество столбцов, вы можете распечатать все, начиная со столбца 6 до конца строки:

ls -lA | awk '{ for (i=6; i<=NF; i++) printf("%s ", $i); printf("\n"); } '

Я не получаю пробелы обратно, поэтому я не знаю, почему вы это получаете. Чтобы исправить это, вы можете добавить это:

| sed 's/\\//g'
0 голосов
/ 06 декабря 2009

Это действительно раздражает, когда я вижу конвейеры с awk и grep / sed. Awk - очень мощный инструмент для обработки строк.

ls -laF | awk '
    / \.\.?\/$/ {next}
    / Dec / {for (i=1; i<=5; i++) $i = ""; print} 
' | sort -r | head -5
0 голосов
/ 06 декабря 2009

хорошо, вы можете сбросить . и .., добавив grep -v "\." | grep -v "\.\."

не уверен насчет остальных

...