如果当我通过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
为什么不使用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
。你明白了这一点,根据你的需求量身定做。)
这是超级老,但我需要答案,很难找到它。我并不真正关心单线部分;我只是需要它完成。这是肮脏的,需要你计算列数。我不是在寻找一个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
以下将仅列出文件名,每行中包含一个文件。
$ ls -1
包括 。档
$ ls -1a
请注意,参数是数字“1”,而不是字母“l”。
假设你不准备做:
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}
- 并且要注意在系统之间迁移。
好吧,如果你正在使用没有空格的文件名,你可以这样做:
grep 'rwx\S*$'
除了你可以使用模式匹配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”开头的文件
作为一个简单的hack,只需在文件名之前添加一个空格,这样就不会匹配输出的开头:
ls -al | grep '\srwx'
编辑:好的,这不像应该的那样健壮。这是awk:
ls -l | awk ' $9 ~ /rwx/ { print $0 }'
这对我来说很有用,不像ls -l和其他人所指出的那样。我喜欢这个,因为它非常通用并给我基本文件名,它删除文件前的路径名。
ls -1 /path_name |awk -F/ '{print $NF}'
这只需要一个命令 -
ls -al | gawk '{print $9}'
你可以用这个:
ls -p | grep -v /