104

While playing with awk I came to execute:

ls -la >> a.txt ; awk {'print $5  $1'} a.txt ;

This is giving output like:

53277-rw-------
52347-rw-------

How can I get a space between these two friends of output?

4
  • 1
    As an advice, you should not parse the output of ls. This will bite you in the back sooner or later. Dec 23, 2012 at 10:08
  • In awk, to concatenate two strings, you just place them side-by-side -- print $5 $1 Dec 23, 2012 at 12:31
  • 3
    Possible duplicate of How do I select a field/column from the output of `ls -l`?
    – kenorb
    Apr 10, 2016 at 4:28
  • 2
    @kenorb and close voters, the linked duplicate is not a duplicate at all. They know already how to print fields by premise (awk {'print $5 $1'} a.txt). They're asking how to put a space in between field #1 and field #5.
    – kos
    Apr 11, 2016 at 17:49

5 Answers 5

130

Just change the line to

ls -la >> a.txt ; awk {'print $5 "        " $1'} a.txt ;

this should print the output with spaces.

Hope this helps.

Edit:

As suggested by McNisse you can use printf, which would provide you good output format

ls -la >> a.txt ; awk {'printf ("%5s\t%s\n", $5, $1)'} a.txt ;
3
  • 8
    The printf function provides better control, specially if you want to format numbers. printf("%s\t%s\n", $5, $1)
    – McNisse
    Dec 23, 2012 at 10:11
  • 1
    Is there a typo in above answer? what does 5s mean in awk {'printf ("%5s\t%s\n", $5, $1)'}
    – Vishal
    Oct 15, 2019 at 13:06
  • @Vishal - if you insert a number after the % sign, then you specify a field width, in this case 5. The output will be right aligned. If you enter a negative number, the output will be aligned on the left.
    – twan163
    Nov 22, 2019 at 15:55
101

Another awk-specific technique, use the "output field separator"

ls -la | awk -v OFS='\t' '{print $5, $1}'

The comma is crucial here.

3
  • this works but cause $1 to go to newline Oct 26, 2016 at 21:47
  • @loretoparisi, no it doesn't. There are likely to be \r characters at your end-of line. Sep 28, 2021 at 13:15
  • +1, This is a clean way to do it. Please note that doesn't work with print $0 to print all fields with the OFS separator, so for such a need we can use column: ... | column -s ' ' -t
    – 4wk_
    Apr 3, 2023 at 9:36
26

A simple way to get tabs is:

awk {'print $5"\t"$1'}
1
  • 1
    Thanks I hate it. But slightly less than the other options.
    – daknowles
    Apr 25, 2020 at 14:59
9

I know this is an old thread, but I'm just learning and found these posts helpful. My best solution was to use gawk to insert spaces between the variables for you.

ls -la | gawk '{print $1, $9}'
2
  • 4
    -1: Nothing new. gawk, mawk, or any other awk, they all insert spaces if you use the comma, which is what this answer says.
    – muru
    Sep 18, 2014 at 23:19
  • 1
    Should be ls -la | awk '{print $1, $9}'. As muru said gawk isn't necessary. Aug 25, 2015 at 16:33
6

To place the space between the arguments, just add " ", e.g. awk {'print $5" "$1'}.

However it is not recommended to parse output of ls command, since it's not reliable and output is for humans, not scripts. Therefore use alternative commands such as find or stat.

Here is example using GNU stat:

$ stat -t *
001.txt 23 8 81a4 501 20 1000004 242236402 1 0 0 1460260387 1460260239 1460260239 1460260194 4096
7c1c.txt 21 8 81a4 501 20 1000004 242236595 1 0 0 1460261322 1460260486 1460260486 1460260486 4096

which will print you machine-friendly output (in terse form), so you can get exactly what you need. Then use -c to use specific format, or use awk, cut or read to get the right columns.

Check stat --help for further options. For example to print day of modification, check this example.

1
  • It appears the OP is trying to parse the output for human reading purposes and not for the purposes of running a script (like for i in ls; do $i).
    – mchid
    Nov 5, 2019 at 18:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .