Легко получите конкретный столбец от вывода без sed или awk

Команда оболочки для изменения привязок клавиш bindkey, Клавиша Backspace, по-видимому, отправляет байт 127 (^?; проверьте ввод Ctrl+V затем Клавиша Backspace), и команда выпуска для удаления символа назад backward-delete-char. Так вставляет это Ваш ~/.tcshrc:

bindkey '^?' backward-delete-char
4
15.08.2013, 00:24
9 ответов

Я не уверен почему

ls -hal / | awk '{print $5, $9}'

кажется, Вам намного более разрушителен к Вашим мыслительным процессам, чем

ls -hal / | cut -d'\s' -f5,9

был бы, имел его, работал. Необходимо ли было бы действительно записать это? Только требуются некоторые awk строки прежде, чем добавить {} становится автоматическим. (Для меня самая твердая проблема помнит, которому соответствует полевое число, какая часть данных, но возможно у Вас нет той проблемы.)

Вы не должны использовать все функции awk; для просто вывода определенные столбцы необходимо знать очень мало awk.

Раздражающая проблема была бы то, если бы Вы хотели произвести символьную ссылку, а также имя файла, или если Ваши имена файлов могли бы иметь пробелы в них. (Или, худшие, новые строки). С гипотетическим regex-осведомленным сокращением это не проблема (за исключением новых строк); Вы просто заменили бы -f5,9 с -f5,9-. Однако нет никакого awk синтаксиса для "полей 9 до конца", и Вас оставляют с необходимостью помнить, как записать для цикла.

Вот немного сценария оболочки, который поворачивается cut- стиль -f опции в awk программу, и затем запускают awk программу. Этому нужна намного лучшая проверка ошибок, но это, кажется, работает. (Добавленная премия: дескрипторы -d опция путем передачи его awk программе.)

#!/bin/bash
prog=\{
while getopts f:d: opt; do
  case $opt in
    f) IFS=, read -ra fields <<<"$OPTARG"
       for field in "${fields[@]}"; do
         case $field in
           *-*) low=${field%-*}; high=${field#*-}
                if [[ -z $low  ]]; then low=1; fi
                if [[ -z $high ]]; then high=NF; fi
                ;;
            "") ;;
             *) low=$field; high=$field ;;
         esac
         if [[ $low == $high ]]; then
           prog+='printf "%s ", $'$low';'
         else
           prog+='for (i='$low';i<='$high';++i) printf "%s ", $i;'
         fi
       done
       prog+='printf "\n"}'
       ;;
    d) sep="-F$OPTARG";;
    *) exit 1;;
  esac
done
if [[ -n $sep ]]; then
  awk "$sep" "$prog"
else
  awk "$prog"
fi

Быстрый тест:

$ ls -hal / | ./cut.sh -f5,9-
7.0K bin 
5.0K boot 
4.2K dev 
9.0K etc 
1.0K home 
8.0K host 
33 initrd.img -> /boot/initrd.img-3.2.0-51-generic 
33 initrd.img.old -> /boot/initrd.img-3.2.0-49-generic 
...
9
27.01.2020, 20:46

Я полагаю, что нет никакого простого решения, чем sed или awk. Но можно записать собственную функцию.

Вот функция списка (вставка копии к Вашему терминалу):

function list() { ls -hal $1 | awk '{printf "%-10s%-30s\n", $5, $9}'; }

затем использование перечисляет функцию:

list /

list /etc
4
27.01.2020, 20:46
  • 1
    На самом деле проблема здесь состоит в том, что функция не берет аргументы, таким образом, она очень узко фокусируется на конкретном случае и не гибка. Если Вы могли бы разработать заключение в кавычки так, чтобы можно было передать аргументы в него, которые были бы полезны. И, конечно, удалите все перед каналом, таким образом, можно использовать его с любым произвольным входом, и указывать, какие столбцы Вы хотите. –  iconoclast 14.02.2014, 21:27
  • 2
    , другими словами, воссоздайте awk, но дайте ему другое имя и меньше функций –  Zac Thompson 11.11.2017, 01:09

Вы не можете только говорить о "столбцах", также не объясняя, каков столбец!

Очень распространенный в обработке текста Unix имеет пробел как столбец (поле) разделитель и (естественно) новая строка как строка или разделитель записей. Затем awk превосходный инструмент, который очень читаем также:

# for words (columns) 5 and 9:
ls -lah | awk '{print $5 " " $9}'
# or this, for the fifth and the last word:
ls -lah | awk '{print $5 " " $NF}'

Если столбцы вместо этого заказаны символьно-мудрые, возможно cut -c лучше.

ls -lah | cut -c 31-33,46-

Можно сказать awk использовать других разделителей полей с -F опция. Если Вы не используете -c (или -b) с cut, использовать -f указывать который столбцы произвести.

Прием является знанием о входе

Вообще говоря, это - не всегда хорошая идея проанализировать вывод ls, df, ps и подобные инструменты с относящимися к обработке текстов инструментами, по крайней мере, не, если Вы хотите быть портативными/совместимыми. В тех случаях попытайтесь вызвать вывод в определенном формате POSIX. Иногда это может быть достигнуто путем передачи определенной опции (-P возможно) к команде, генерирующей вывод. Иногда путем установки переменной среды такой как POSIXLY_CORRECT или вызов определенного двоичного файла, такой как /usr/xpg4/bin/ls.

2
27.01.2020, 20:46

Это может быть тривиально, но как насчет этого?

ls -hal / |
    while IFS=' ' read x x x x five x x x nine etc;
        do echo $five $nine;
    done

Просто примите во внимание тот факт, что переменные x, five, nineи etcокажутся в области видимости оболочки sub -...:)

0
27.01.2020, 20:46

Это старый вопрос, но, рискуя раскачать лодку, я должен сказать, что согласен с @iconoclast :, действительно должен быть хороший, простой способ извлечения выбранных столбцов в Unix.

Теперь, да, awkможет легко это сделать, это правда. Но я думаю, что также верно и то, что это «излишество» для простой, обычной задачи. И даже если фактор избыточности не вызывает беспокойства, дополнительный ввод, безусловно, :, учитывая, как часто мне приходится извлекать столбцы, я бы действительно предпочел не набирать print, и эти фигурные скобки, и эти знаки доллара, и эти цитаты, каждый раз. И если существование awkи sedдействительно подразумевает, что нам не нужен простой экстрактор столбцов, то, по тому же принципу, я думаю, нам не нужен и grep!

Утилита cutдолжна быть ответом, но она, к сожалению, сломана. По умолчанию это не «столбцы, разделенные пробелами», несмотря на (IMO )подавляющее преобладание этой потребности. И, на самом деле, он вообще не может выполнять произвольное разделение пробелов! (Итак, вопрос иконоборца.)

Около 35 лет назад, еще до того, как я услышал о cut, я написал свою собственную версию. Это работает хорошо; Я все еще использую его каждый день; Я рекомендую его всем, кто хочет лучшего cutи не зацикливается на использовании только «стандартных» инструментов. У него есть один существенный недостаток в том, что его имя, "столбец", с тех пор используется утилитой BSD .

В любом случае, имея в руках эту версию column, мой ответ на вопрос бунтаря

ls -hal / | column 5 9

или если хотите

ls -hal / | column 5,9

Man-страница и архив с исходным кодом по адресуhttp://www.eskimo.com/~scs/src/#column. Используйте его, если вам интересно; проигнорируйте это как ответ вне темы -, я полагаю, это если вы не.

2
01.09.2021, 11:52

Вы можете найти команду

ls -hal| awk 'NR>1{print $(NF-4),$NF}'

Второй вариант

find . -maxdepth 1 -type f -printf "%s %p\n"
0
02.09.2021, 19:33

Я удивлен, что никто еще этого не написал, но если ваше единственное возражение против cutзаключается в том, что он не будет обрабатывать повторяющиеся пробелы как один разделитель, как насчет того, чтобы просто сжать повторяющиеся пробелы? Это одно из применений tr.

ls -l | tr -s ' ' | cut -d ' ' -f5,9

Учитывая вывод ls -l, показанный в вашем вопросе, результат будет:

1.2K.
1.2K..
15K.DS_Store
272B.DocumentRevisions-V100
102B.MobileBackups
170B.Spotlight-V100
68B.Trashes
136B.bzvol
0B.dbfseventsd
0B.file
42K.fseventsd
68B.vol
9.6K Applications
238B Developer
2.3K Library
68B Network
136B System
204B Users
204B Volumes
1.3K bin
68B cores
4.8K dev
11B etc
1B home
7.8M mach_kernel
1B net
204B private
2.3K sbin
11B tmp
442B usr
11B var
1
02.09.2021, 20:13

Если вы просто хотите отобразить эти два атрибута (размер и имя ), вы также можете использовать инструмент stat(, который предназначен именно для этого -запроса атрибутов файла):

stat -c "%s  %n".* *

отобразит размер и имя всех файлов (, включая «скрытые» файлы )в текущем каталоге.

Замечание.:Вы выбрали lsв качестве примера приложения для случаев использования, когда вы хотите извлечь определенные столбцы из выходных данных программы. К сожалению, lsявляется одним из примеров, когда вам действительно следует избегать использования инструментов обработки текста -для разбора вывода.

1
03.09.2021, 07:31

Вывод lsникогда не следует анализировать. Разбор lsсложен, ширина столбцов различается, количество столбцов может меняться в середине вывода -,...

Используйте команду stat(man stat). statпозволит вам вывести нужные данные в нужном вам формате.

Например,

stat --format="%s %n" *.*
0
07.09.2021, 23:27

Теги

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