如何正确地从ls -al grep文件名

时间:2012-03-04 23:14:15

标签: unix grep ls

当我通过ls滚动时,如果“filename”匹配,我怎么告诉grep只打印出行?我想让它忽略每一行上的所有内容,直到时间戳之后。必须有一些简单的方法才能在一个命令上执行此操作。

正如你所看到的,没有它,如果我搜索文件“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 个答案:

答案 0 :(得分:12)

以下内容仅列出文件名,每行列出一个文件。

$ ls -1     

包含。文件

$ ls -1a 

请注意,参数为数字“1”,而不是字母“l”。

答案 1 :(得分:3)

为什么不使用grep并匹配时间戳后面的文件名?

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

[0-9]{2}:[0-9]{2}是暂时的,$FILENAME是您放置rob robrwx的位置,尾随(\.[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 :(得分:2)

假设你不准备这样做:

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

然后你需要利用在文件名开始之前有8个空格分隔列的事实。使用egrep(或grep -E),您可以执行以下操作:

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

这在第8列之后查找'rwx'。如果您希望名称以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},并注意在系统之间进行迁移。

答案 3 :(得分:1)

好吧,如果你正在使用没有空格的文件名,你可以这样做:

grep 'rwx\S*$'

答案 4 :(得分:0)

作为一个简单的hack,只需在文件名之前添加一个空格,这样就不会与输出的开头匹配:

ls -al | grep '\srwx'

编辑:好的,这不像应该的那样健壮。这是awk:

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

答案 5 :(得分:0)

除了你可以使用模式匹配ls,exaple ksh和bash之外, 这可能是你应该做的,你可以使用文件名出现在a中的事实 固定位置。 awk(gawk,nawk或者你有)是一个更好的选择。 如果你必须使用grep它闻起来像家庭作业给我。请用这种方式标记。

假设文件名起始位置基于linux中ls -l的输出: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”

开头的文件

答案 6 :(得分:0)

这对我有用,不像ls -l&amp;一些人指出的其他人。我喜欢这个,因为它非常通用&amp;给我基本文件名,它删除文件前的路径名。

ls -1 /path_name |awk -F/ '{print $NF}'

答案 7 :(得分:0)

您只需要一个命令 -

ls -al | gawk '{print $9}'

答案 8 :(得分:0)

您可以使用:

ls -p | grep -v / 

答案 9 :(得分:0)

这是超老的,但我需要答案,很难找到它。我不是很在乎单线部分。我只需要完成它。这是肮脏的,需要您对列进行计数。我不是在这里寻找支持,只是为将来的搜索者留下了一些选择。

有用的awk技巧是here- 使用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替换var,将脚本放入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)


在另一个注释上:radical.coffee your answer。它没有解决我这个问题的版本,所以我没有赞成,但我喜欢您的正则表达式细目:D