Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

How can the output of ls -l be modified to separate fields using tabs instead of spaces? I want to paste the output into a spreadsheet; the padding with a variable number of spaces makes it difficult to do so. To illustrate:

drwxr-xr-x  2 root root     4096 Sep 26 11:43 wpa_supplicant
-rw-r-----  1 root dialout    66 Sep 26 11:43 wvdial.conf
drwxr-xr-x  9 root root     4096 Oct  8 08:21 X11
drwxr-xr-x 12 root root     4096 Feb 18 23:31 xdg
drwxr-xr-x  2 root root     4096 Jan 31 06:11 xml
drwxr-xr-x  2 root root     4096 Nov 22 07:26 xul-ext
-rw-r--r--  1 root root      349 Jan 13  2012 zsh_command_not_found

In the excerpt from ls -l /etc shown above, rows 1, 2 and 3 have a single digit in column 2 whereas row 4 has two. That means the alignment is achieved by using two spaces for separating columns 1 and 2 in rows 1-3, but just one space in row 4.

share|improve this question
add comment

3 Answers

up vote 2 down vote accepted

I've made a shell script for the same. It takes care of the cases when the filenames have spaces or any other special characters.

#! /bin/bash

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for file in $(ls)
do
    stat --printf="%A\t%h\t%U\t%G\t%s\t" $file
    mod_epoch=$(stat --format="%Y" $file)
    mod_month=$(date -d @$mod_epoch +"%b")
    mod_day=$(date -d @$mod_epoch +"%d")
    mod_time=$(date -d @$mod_epoch +"%H:%M")
    printf "%s\t%s\t%s\t%s\n" $mod_month $mod_day $mod_time $file
done
IFS=$SAVEIFS
  • Save it to a file, say ls_tab.sh
  • Make it executable:
chmod +x ls_tab.sh
  • Run it:
./ls_tab.sh

Note: This can be done by parsing the output of ls, however the reason why it should not be done is given here.

share|improve this answer
1  
If the goal is to know what ls says, parsing its output is fine. That is rarely the goal. Arguably it is here. I think the method you've used is quite good (any method will produce undesired results given some set of needs)! However, arguably parsing ls might be better. Consider the case of a filename that actually has a tab character in it. ls -l replaces the tab with a ? character. Your script preserves the tab character, which will create extra columns if its output is interpreted as tab-delimeted and used to create a spreadsheet. It degrades badly if a filename has a newline. –  Eliah Kagan Mar 26 '13 at 14:37
1  
True. But normally files do not have \n or \t in their names. If they do, then parsing the output of ls with simple bash commands will be more complex, but can be achieved. I can update the answer, if the OP wants to handle such cases. –  green7 Mar 26 '13 at 16:17
    
This works for me and long filenames with spaces in them display properly. My usage is fairly simple and I hope not to deal with files with \n and \t in their names. –  user25656 Mar 26 '13 at 17:17
1  
Perfect. For Windows speadsheet use printf "%s\t%s\t%s\t%s\r\n" $mod_month $mod_day $mod_time $file and to redirect the ouptut the file as ./ls_tab.sh > listing.txt. –  Fedir Jun 10 '13 at 9:23
add comment

Try:

ls -l | awk -v OFS="\t" '$1=$1'

Or, if your filenames have spaces:

ls -l | awk '{print $1,"\t",$2,"\t",$3,"\t",$4,"\t",$5,"\t",$6,"\t",$7,"\t",$8,"\t",$9,$10,$11,$12,$13,$14,$15;}'
share|improve this answer
    
+1. Works perfectly. This sort of thing is precisely what awk is for. Clever! –  tgies Mar 26 '13 at 16:08
    
Unfortunately this does not work correctly for filenames that contain spaces. It replaces them with tabs as well. While this is simpler and runs faster than green7's script based solution, this will produce incorrect output a large amount of the time, and has no advantages over Aditya's method. Can this be modified so that spaces are no longer interpreted as input delimeters, after the 9th column? –  Eliah Kagan Mar 26 '13 at 16:29
1  
please see update –  philshem Mar 26 '13 at 16:41
    
@psny18 The updated way is even more badly broken. It cuts off everything but the first word of each filename. Simply writing $9 does not change the fact that you have awk always interpreting spaces as indicating a break between columns. $9 captures only the first word in that position, and since the other words are considered separate, higher-numbered columns, they are never printed at all. –  Eliah Kagan Mar 26 '13 at 16:45
    
That's a pity that filenames aren't treated as one column even if they have spaces in them. –  user25656 Mar 26 '13 at 17:22
show 5 more comments

We do not even need to convert the output as Tab Delimited. Space between columns is just fine enough.

Run your ls -l command in terminal as you normally do and copy the contents you wish to be pasted in a Spreadsheet.

terminal command

Next, open your Spreadsheet program (LibreOffice Calc in my case) and press Ctrl + V to paste the contents of your clipboard.

The Text Import Wizard would pop up. Make sure you put a checkmark beside Space and press Ok. You can watch the preview in the lower pane.

Libo Text Import

share|improve this answer
1  
This won't work when filenames have spaces –  green7 Mar 26 '13 at 14:24
    
@green7: Ah.. Didn't realize that! :-) –  Aditya Mar 26 '13 at 14:30
    
Not just the filenames but also the number of characters in columns. Padding there and elsewhere causes problems if "space" is chosen as the delimiter. I'll edit the question to illustrate that. –  user25656 Mar 26 '13 at 15:50
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.