Удалить первые 8 столбцов из вывода ls с помощью AWK

381
Jesus DA

Я хотел бы использовать AWK, чтобы удалить первые 8 столбцов из следующего вывода:

 ls -l  lrwxrwxrwx 1 user user 23 jul 27 00:04 file1.pdf -rw-rw-r-- 1 user user 107 may 8 13:59 file 2 with spaces.mp3 lrwxrwxrwx 1 user user 11 jul 24 19:43 file3-with-hyphens.txt lrwxrwxrwx 1 user user 11 jul 24 19:43 and_another_file4_with_underscores.md -rw-rw-r-- 1 user user 107 may 8 13:59 file 5 with way more spaces than the rest.mp3 

и отправьте результат в текстовый файл. Я могу сделать это вручную в vim с визуальным выбором блока, однако я бы предпочел иметь скрипт для этого автоматически.

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

Мой окончательный код следующий:

awk '' x=1 ~/file_folder_content.txt | awk '' x=1 | ... | awk '' x=1 >> ~/file_folder_content.txt 

Примечание 1: Я ожидаю, что фактический результат lsкоманды будет намного больше, чем этот.

Примечание 2: я попытался напечатать 9-е поле, но так как некоторые имена файлов содержат пробелы, это печатает только первое слово в имени файла.

1
Удалить первые 8 столбцов? Этот вывод имеет только 8 столбцов. Вы пытаетесь просто напечатать имена файлов? `ls -1` делает это. confetti 6 лет назад 1
Метод проб и ошибок оставил меня с этой нелепой командой: `ls -l | tail -n +2 | столбец -tdN тест -o "|" | cut -d "|" -f 9` - печатает только 9-й столбец. Должен быть лучший способ, но эй, это работает, лол. confetti 6 лет назад 0

2 ответа на вопрос

1
simlev

Это должно делать то, что вы хотите в awk:

ls -l | awk '$9~/./; gsub(/^ +/,""); print}' 

Вот немного другой подход в perl:

ls -l | perl -lane 'if ($F[7]=~/./) ' 

Примечание: я не могу не рекомендовать вам тщательно подумать о том, чего вы на самом деле хотите достичь, поскольку могут быть более эффективные способы. Как уже упоминалось @confetti, просто печатать имена файлов проще с помощью ls -1.

Примечание. Как правильно указано в комментариях, это решение не является надежным. Я бы добавил, что никакой разбор не lsможет считаться безопасным и исправным.

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

Создайте файл с несколькими последовательными пробелами в имени и посмотрите, что ваша команда напечатает для него. Kamil Maciorowski 6 лет назад 1
(для awk) или файл с именем `0000` или` -00.00` или `0e42` dave_thompson_085 6 лет назад 1
@ dave_thompson_085 законное наблюдение! Этот существенный случай может быть учтен заменой `$ 9` на` $ 9 ~ /./ `и` $ F [7] `на` $ F [7] = ~ /./ `, но вся идея парсинга` ls `вывод должен быть пересмотрен. simlev 6 лет назад 0
@simlev Более широкая проблема, которую я пытаюсь решить, - овладеть AWK, так что это была просто проблема, с которой я столкнулся на практике, но не смог найти способ ее решения (за исключением кода, который я предоставил ). Я ожидал, что это будет довольно неэффективным способом ведения дел, но также ожидал, что узнаю лучший способ сделать это в процессе. Jesus DA 6 лет назад 0
@simlev Я вычислил вывод из вашего ответа моим отредактированным вручную файлом, и они равны, так что это ответ, который я искал. Кроме того, он дает лучший способ сделать это и упоминает недостатки парсинга результата от `ls`. Jesus DA 6 лет назад 0
0
Kamil Maciorowski

Это похоже на проблему XY . ls -1должен напечатать, что вы хотите. Этот параметр требуется POSIX, поэтому вряд ли вы lsего не поддерживаете.

Однако, если вы собираетесь анализировать результат, вы не должны использовать егоls вообще. Используйте find, желательно с -print0действием.

Так что lsэто не правильный инструмент. Если вы настаиваете на том, что lsвсе равно анализируете пустой вывод, то, awkвозможно, это не тот инструмент. Обоснование:

  • Ваши столбцы разделены пробелами; иногда есть два или три последовательных пробела, это отличается от строки к строке. Таким образом, с этим наивным разделителем имя файла в одной строке может начинаться с N-го столбца, а с другой строки - с (N + 1) -го столбца.
  • Вы можете указать awkобрабатывать несколько пробелов как один разделитель ( awk -F ' +'), но это будет искажать имена файлов с множеством последовательных пробелов.
  • Поэтому вам нужна логика, чтобы определить, где имя файла начинается в каждой строке. Это можно сделать (я думаю, awkчто Тьюринг завершен), но я не могу дать вам никакого рабочего решения.

Даже вывод ls -1не должен быть проанализирован, ls -lхуже.

Как только вы укажете, что ls не является надежным, больше не стоит размышлять о том, как его можно проанализировать с помощью какого-либо конкретного инструмента. Чтобы доказать, насколько это бесполезно, у меня, например, есть имена групп, которые содержат пробелы. simlev 6 лет назад 0

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