문제

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

when I write the ls -la | sed -n 's/\(..........\) \(.*\).*$/\1/p' It show the following output.

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

But I need the following output.

Size  
 26    
4096

Note that I need to use sed. And also I need to sort the sizes from largest to smallest and need shows the largest 3 files only.

도움이 되었습니까?

해결책 2

The general caveat applies: awk is the better tool for the job.

Here's a simpler sed solution:

ls -la | sed -E 's/^(([^[:space:]]+)[[:space:]]+){5}.*/\2/'
  • works with both spaces and tabs between columns
  • takes advantage of repeating capture groups only reporting the last captured instance - in this case, the 5th column
  • caveat: will not work correctly with filenames with embedded spaces

In case only spaces separate the columns - which is the case with ls output, the command simplifies to:

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

To skip the first input line you have several options, but the simplest is to prepend 1d to your sed program:

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

(Other options:

Use tail to skip the first line:

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

More generically, use sed to ignore lines that do not have at least 5 columns:

ls -la | sed -E -n 's/^(([^ ]+)[ ]+){5}.*/\2/p'
  • -n suppresses default output
  • appending p to the substitution command only produces output if a substitution was made

)

To show only the 3 largest files (a requirement added later by the OP), courtesy of @JS웃:

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

The above will not output the header line, however. To include the header line, use (courtesy of this unix.stackexchange.com answer):

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

다른 팁

Use the right tool for the job. If you're processing columns, awk is a better solution:

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

Given your ls -la output, that should generate:

Size
26
4096

If, for some bizarre reason you cannot use the correct tool, the following sed command will work, but it's rather ugly:

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

It works by removing from the year column (9999-) and preceding tabs/spaces, to the end of the line.

Then it does something similar for the header.

Then it just removes everything from line start to the final tab/space, which is now just before the size column.

I know which one I'd prefer to write and maintain :-)

Here is another way with GNU sed:

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

If your version of sed does not support -r option, then use -E.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top