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

问题描述 投票:5回答:10

如果当我通过ls管道时“文件名”匹配时,如何告诉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
unix grep ls
10个回答
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

。你明白了这一点,根据你的需求量身定做。)


0
投票

这是超级老,但我需要答案,很难找到它。我并不真正关心单线部分;我只是需要它完成。这是肮脏的,需要你计算列数。我不是在寻找一个upvote,只为未来的搜索者留下一些选择。

有用的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换掉vars,把脚本扔进你的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

(lol; P)


在另一个说明:mathematical.coffee your answer是rad。它没有解决我的这个问题的版本,所以我没有upvote,但我喜欢你的正则表达式分解:D


12
投票

以下将仅列出文件名,每行中包含一个文件。

$ ls -1     

包括 。档

$ ls -1a 

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


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} - 并且要注意在系统之间迁移。


1
投票

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

grep 'rwx\S*$'

0
投票

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

假设文件名起始位置基于linux:56中ls -l的输出

-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
投票

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

ls -al | grep '\srwx'

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

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

0
投票

这对我来说很有用,不像ls -l和其他人所指出的那样。我喜欢这个,因为它非常通用并给我基本文件名,它删除文件前的路径名。

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

0
投票

这只需要一个命令 -

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

0
投票

你可以用这个:

ls -p | grep -v / 
© www.soinside.com 2019 - 2024. All rights reserved.