Возможно ли использовать grep только для одного столбца и одновременно печатать другие ВЫБРАННЫЕ выходные данные

#linux #bash

#linux #баш

Вопрос:

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

 #ls -l
  

выводит меня что-то вроде этого

 -rw-r--r-- 1 root root   5110 2011-10-08 19:36 test.txt
-rw-r--r-- 1 root root   5111 2011-10-08 19:38 test.txt
-rw-r--r-- 1 root root   5121 2011-10-08 19:36 5110.txt
-rw-r--r-- 1 root root   5122 2011-10-08 19:38 5111.txt
  

Допустим, я хотел использовать grep для поиска всех имен файлов, содержащих '511' и распечатывающих размер / имя файла.

Как мне использовать grep для имен '511' файлов, по-прежнему выводить размер файла и не допускать, чтобы выходные данные содержали две верхние строки.

большое вам спасибо, чтение справочных страниц мне в этом не помогло.

Ответ №1:

Вы можете использовать awk для этого:

 pax:~$ echo '
-rw-r--r-- 1 root root   5110 2011-10-08 19:36 test.txt
-rw-r--r-- 1 root root   5111 2011-10-08 19:38 test.txt
-rw-r--r-- 1 root root   5121 2011-10-08 19:36 5110.txt
-rw-r--r-- 1 root root   5122 2011-10-08 19:38 5111.txt
' | awk '{if (substr($8,1,3)=="511"){print $5" "$8}}'

5121 5110.txt
5122 5111.txt
  

Он просто проверяет поле 8 (имя файла), чтобы увидеть, начинается ли оно с «511», и, если да, выводит поля 5 и 8, размер и имя.

Комментарии:

1. Святая корова. Я пытался использовать awk, но не знал, как выполнить оператор if. Очень полезная информация. Спасибо!

2. Это работает некорректно для файлов с пробелами в их имени. Это не так сложно исправить.

3. Кроме того, substr ищет совпадения только в начале имени файла, а не где-либо в имени. Опять же, это не так сложно исправить, но ls следует избегать синтаксического анализа выходных данных.

4. Более простое решение: awk '$8 ~ /.*511.*/ {print $5" "$8}'

5. uzsolt. Как это называется? Как я могу получить больше информации об этом синтаксисе и что все это значит.

Ответ №2:

 find . -name '*511*' -printf "%st%pn"
  

Комментарии:

1. Возможно, добавить -maxdepth 0 , чтобы предотвратить find попадание в подкаталоги.

Ответ №3:

Если вы хотите отфильтровать только имя файла, почему вы в первую очередь перечисляете другие файлы?

 ls -l *511* | cut -c23-30,48-
  

или даже с awk ;

 ls -l *511* | awk '{ $1 = $2 = $3 = $4 = $6 = $7 = ""; print }'
  

Однако выходные данные ls не являются полностью надежными, поэтому вам следует избегать их прямой обработки.

 perl -le 'for (@ARGV) { print ((stat($_))[7], " $_") }' *511*
  

stat() Системный вызов возвращает необработанную информацию, отображаемую ls в машиночитаемом формате. Любой инструмент, который дает вам доступ к этой информации, подойдет; он не обязательно должен быть Perl.

Ответ №4:

Вы можете обойти ls и просто использовать bash имя файла glob :

 for f in 511*
do
    echo $f $(stat --format '%s' $f)
done