Как правильно grep имена файлов только из ls -al - PullRequest
5 голосов
/ 05 марта 2012

Как мне сказать, что grep распечатывает строки, только если "имя файла" совпадает, когда я передаю через ls? Я хочу, чтобы он игнорировал все в каждой строке до окончания отметки времени. Должен быть простой способ сделать это с помощью одной команды.

Как видите, без него, если бы я искал файл "rwx", он вернул бы не только строку с rwx.c, но и первые три строки из-за разрешений. Я собирался использовать AWK, но я хочу, чтобы он отображал всю последнюю строку, если я ищу «rwx».

Есть идеи?

РЕДАКТИРОВАТЬ: Спасибо за хаки ниже. Однако было бы здорово иметь более безошибочный метод. Например, если бы у меня был файл с именем «rob rob», я бы не смог использовать заявленные решения.

drwxrwxr-x 2 rob rob  4096 2012-03-04 18:03 .
drwxrwxr-x 4 rob rob  4096 2012-03-04 12:38 ..
-rwxrwxr-x 1 rob rob 13783 2012-03-04 18:03 a.out
-rw-rw-r-- 1 rob rob  4294 2012-03-04 18:02 function1.c
-rw-rw-r-- 1 rob rob   273 2012-03-04 12:54 function1.c~
-rw-rw-r-- 1 rob rob    16 2012-03-04 18:02 rwx.c
-rw-rw-r-- 1 rob rob    16 2012-03-04 18:02 rob rob

Ответы [ 10 ]

12 голосов
/ 02 ноября 2012

Ниже будут перечислены только имя файла и один файл в каждой строке.

$ ls -1     

Включить. файлы

$ ls -1a 

Обратите внимание, что аргументом является число "1", а не буква "l".

3 голосов
/ 05 марта 2012

Почему вы не используете grep и не сопоставляете имя файла с отметкой времени?

grep -P "[0-9]{2}:[0-9]{2} $FILENAME(\.[a-zA-Z0-9]+)?$"

[0-9]{2}:[0-9]{2} - это время, $FILENAME - то, куда вы положите rob robили rwx, а конечный (\.[a-zA-Z0-9]+)? должен допускать необязательное расширение.

Редактировать : @JonathanLeffler ниже указывает, что когда файлы старше 6 месяцев, столбец временизаменяется на год - это то, что происходит на моем компьютере в любом случае.Вы можете сделать ([0-9]{2}:[0-9]{2}|(19|20)[0-9]{2}), чтобы указать время ИЛИ год, но вам лучше всего использовать awk (?).

[foo@bar ~/tmp]$ls -al
total 8
drwxrwxr-x  2 foo foo 4096 Mar  5 09:30 .
drwxr-xr-- 83 foo foo 4096 Mar  5 09:30 ..
-rw-rw-r--  1 foo foo    0 Mar  5 09:30 foo foo
-rw-rw-r--  1 foo foo    0 Mar  5 09:29 rwx.c
-rw-rw-r--  1 foo foo    0 Mar  5 09:29 tmp

[foo@bar ~/tmp]$export filename='foo foo'

[foo@bar ~/tmp]$echo $filename
foo foo

[foo@bar ~/tmp]$ls -al | grep -P "[0-9]{2}:[0-9]{2} $filename(\.[a-zA-Z0-9]+)?$"
-rw-rw-r--  1 cha66i cha66i    0 Mar  5 09:30 foo foo

(Вы можете дополнительно расширить соответствие всей строке, если хотите:

^                              # start of line
[d-]([r-][w-][x-]){3} +        # permissions & space (note: is there a 't' or 's'
                               # sometimes where the 'd' can be??)
[0-9]+                         # whatever that number is
[\w-]+ [\w-]+ +                # user/group (are spaces allowed in these?)
[0-9]+ +                       # file size (modify for -h switch??)
(19|20)[0-9]{2}-               # yyyy (modify if you want to allow <1900)
(1[012]|0[1-9])-               # mm
(0[1-9]|[12][0-9]|3[012]) +    # dd
([01][0-9]|2[0-3]):[0-6][0-9] +# HH:MM (24hr)
$filename(\.[a-zA-Z0-9]+)?     # filename & optional extension
$                              # end of line

. Вы получаете точку, адаптированную к вашим потребностям.)

2 голосов
/ 05 марта 2012

Предполагая, что вы не готовы сделать:

ls -ld $(ls -a | grep rwx)

тогда вам нужно использовать тот факт, что перед началом имени файла есть 8 столбцов с пробелом. Используя egrep (или grep -E), вы можете сделать:

ls -al | egrep "^([^ ]+ +){8}.*rwx"

Это выглядит как 'rwx' после 8-го столбца. Если вы хотите, чтобы имя начиналось с rwx, пропустите .*. Если вы хотите, чтобы имя заканчивалось на rwx, добавьте $ в конце. Обратите внимание, что я использовал двойные кавычки, чтобы вы могли интерполировать переменную вместо литерала rwx.

Это было проверено на Mac OS X 10.7.3; команда ls -l последовательно дает три столбца для поля даты:

-r--r--r--  1 jleffler  staff   6510 Mar 17  2003 README,v
-r--r--r--  1 jleffler  staff  26676 Mar  3 21:44 ccs.nmd

Ваш ls -l, кажется, дает только два столбца, поэтому вам нужно изменить {8} на {7} для вашей машины - и остерегаться миграции между системами.

1 голос
/ 05 марта 2012

Ну, если вы работаете с именами файлов без пробелов, вы можете сделать что-то вроде этого:

grep 'rwx\S*$'
0 голосов
/ 28 апреля 2019

это очень старый, но мне нужен был ответ, и мне было трудно его найти.я действительно не заботился об одной части лайнера;Мне просто нужно было это сделать.это плохо и грязно и требует, чтобы вы посчитали столбцы.Я не ищу здесь возражений, просто оставляю некоторые варианты для будущих искателей.

полезный awk трюк здесь - Использование awkраспечатать все столбцы от n-го до последнего

, если YOUR_FILENAME="rob rob" и WHERE_FILENAMES_START=8

ls -al | while read x; do
  y=$(echo "$x" | awk '{for(i=$WHERE_FILENAMES_START; i<=NF; ++i) printf $i""FS; print ""}')
  [[ "$YOUR_FILENAME " = "$y" ]] && echo "$x"
done

, если сохранить его как скрипт bash и выгрузитьВАРЫ с $ 2 и $ 1, бросьте скрипт в ваш usr bin ... тогда у вас будет чистый простой однострочный;)

вывод будет:

> -rw-rw-r-- 1 rob rob    16 2012-03-04 18:02 rob rob

вопрос был для однострочника, так что ...

ls -al | while read x; do [[ "$YOUR_FILENAME " = "$(echo "$x" | awk '{for(i=WHERE_FILENAMES_START; i<=NF; ++i) printf $i""FS; print ""}')" ]] && echo "$x" ; done

(смеется; P)


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

0 голосов
/ 24 марта 2016

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

ls -p | grep -v / 
0 голосов
/ 02 сентября 2014

Для этого нужна была только одна команда -

ls -al | gawk '{print $9}'
0 голосов
/ 20 февраля 2014

Это работает для меня, в отличие от ls -l и других, как указали некоторые люди. Мне это нравится, потому что оно действительно общее и дает мне базовое имя файла , которое удаляет пути перед файлом.

ls -1 /path_name |awk -F/ '{print $NF}'
0 голосов
/ 05 марта 2012

Помимо того факта, что вы можете использовать сопоставление с шаблоном с помощью ls, например, ksh и bash, что, вероятно, то, что вы должны сделать, вы можете использовать тот факт, что имя файла происходит в фиксированная позиция. awk (gawk, nawk или что у вас есть) - лучший выбор для этого. Если вам нужно использовать grep, для меня это пахнет домашней работой. Пожалуйста, отметьте это так.

Предположим, что начальная позиция имени файла основана на выводе команды ls -l в linux: 56

-rwxr-xr-x  1 Administrators None    2052 Feb 28 20:29 vote2012.txt

ls -l | awk ' substr($0,56) ~/your pattern even with spaces goes here/'

например.,

ls -l | awk ' substr($0,56) ~/^val/'

найдет файлы, начинающиеся с "val"

0 голосов
/ 05 марта 2012

Как простой взлом, просто добавьте пробел перед вашим именем файла, чтобы вы не соответствовали началу вывода:

ls -al | grep '\srwx'

Редактировать: ОК, это не так надежно, как должно быть.Вот awk:

ls -l | awk ' $9 ~ /rwx/ { print $0 }'
...