无法制定正则表达式以与sed一起使用以提取列值

时间:2014-05-02 04:07:26

标签: linux shell sed text-parsing

ls -la

Permissions   links  Owner  Group  Size   Date        Time    Directory or file
-rwxr--r--     1     User1  root    26    2012-04-12  19:51    MyFile.txt
drwxrwxr-x     3     User2  csstf  4096   2012-03-15  00:12     MyDir

当我写ls -la | sed -n 's/\(..........\) \(.*\).*$/\1/p'时 它显示以下输出。

Permissions   links  Owner    Group  
 -rwxr--r--     1     User1   root    
 drwxrwxr-x     3     User2   csstf  

但我需要以下输出。

Size  
 26    
4096

请注意,我需要使用sed。而且我还需要将大小从最大到最小排序,并且只需要显示最大的3个文件。

3 个答案:

答案 0 :(得分:4)

使用正确的工具完成工作。如果您正在处理列,awk是更好的解决方案:

ls -la | awk '{print $5}'

根据您的ls -la输出,应生成:

Size
26
4096

如果由于某些奇怪的原因你无法使用正确的工具,以下sed命令将起作用,但它相当难看:

sed 's/[ \t]*[0-9][0-9][0-9][0-9]-.*//;s/[ \t]*Date.*//;s/^.*[ \t]//'

它的工作原理是从年份列(9999-)和前面的标签/空格中删除到该行的末尾。

然后它为标题做了类似的事情。

然后它只删除从行开始到最终制表符/空格的所有内容,现在就在大小列之前。

我知道哪个更愿意编写和维护: - )

答案 1 :(得分:0)

一般警告适用:awk是更好的工具。

这是一个更简单的sed解决方案:

ls -la | sed -E 's/^(([^[:space:]]+)[[:space:]]+){5}.*/\2/'
  • 适用于列之间的空格和制表符
  • 利用重复捕获组仅报告最后捕获的实例 - 在本例中为第5列
  • 警告:无法正常使用带有嵌入空格的文件名

如果只有空格将列分开 - 这是ls输出的情况,该命令简化为:

ls -la | sed -E 's/^(([^ ]+)[ ]+){5}.*/\2/' 

跳过第一个输入行,您有多个选项,但最简单的方法是将1d添加到sed程序中:

ls -la | sed -E '1d; s/^(([^ ]+)[ ]+){5}.*/\2/'

(其他选项:

使用tail跳过第一行:

ls -la | tail +2 | sed -E 's/^(([^ ]+)[ ]+){5}.*/\2/'

更一般地,使用sed忽略至少有5列的行:

ls -la | sed -E -n 's/^(([^ ]+)[ ]+){5}.*/\2/p'
  • -n禁止默认输出
  • p附加到替换命令仅在进行替换时生成输出

仅显示3个最大的文件(OP后来添加的要求),@JS court提供:

ls -la | sed -E '2d; s/^(([^ ]+)[ ]+){5}.*/\2/' | sort -nr | head -3

但是,上面不会输出标题行。 要包含标题行,请使用(this unix.stackexchange.com答案提供):

ls -la | sed -E '1d; s/^(([^ ]+)[ ]+){5}.*/\2/' | 
  { IFS= read -r l; echo "$l"; sort -nr | head -3; }

答案 2 :(得分:0)

这是GNU sed的另一种方式:

ls -la | sed -r '1d;s/([^ ]+ *){4}([^ ]+).*/\2/' 

如果您的sed版本不支持-r选项,请使用-E