Cut command: can't make it cut fields

I'm a complete beginner in UNIX (and not a computer science student either), just undergoing a tutoring course. Trying to replicate the instructions on my own I directed output of the ls listing command (lists all files of my home directory ) to My_dir.tsv file (see the screenshot) to make use of cut command so to have columns 1,3,4,9 cut (e.g. "left").

However when I'm trying to execute the command

cut -f 1,3,4,9 My_dir.tsv

nothing happens. I guess it's because the file isn't formatted properly with regard to implementing tabbed spaces. I imagined that automatic formatting, with the deployment of columns I see in output, emerging along with the result of ls is a .tsv file by default but I was wrong.

What should I do to make it work as intended? How do I make a real .tsv file of ls output?

My OS is OS X (Lion).

Hello scrutinizerix,

Could you please confirm it is not a homework, as we do have a special section/forum for homework/projects here. In case it is not homework, could you please let us know clearly what is your requirement because it is not clear in your post, please post your requirement with sample Input_file and expected output. So that we could help you out easily.

Thanks,
R. Singh

My_dir.tsv is empty!?

There are at least three ways to do this, but none of them work perfectly (depending on the number of files present and the collective lengths of their names, whether or not any of the filenames contain space or tab characters, and whether or not any of the filenames contain newline characters).

Note also that the ls utility goes to a lot of work to line up output fields while producing minimal line lengths. Converting the ls -l output to use a single tab as a field separator for all fields is likely to produce wider line lengths on display devices, and, depending on the variability of user and group name lengths, unaligned group and filename output fields.

But, before we can go into details on these possibilities, we do need clarification, as RavinderSingh13 asked, about what a "tutoring course" is.

Homework? No, I'm learning UNIX for OS X on my own using sources bought online. Didn't have a clue of the dedicated section for homework. Will consider in future, thanx.

---------- Post updated at 02:37 PM ---------- Previous update was at 02:25 PM ----------

No, the picture is just contents of My_dir.tsv that is a snapshot of my home directory listing not the actual ls command. It's the My_dir.tsv that is 3.1K in reality.

---------- Post updated at 02:42 PM ---------- Previous update was at 02:37 PM ----------

The course is "Learning UNIX for Mac OS X users" by Kevin Scoglund.

Do I get you right that you want the permissions, owner, group, and file name from ls 's "long listing format" (as the bare ls alone won't yield those fields)? As long as you don't have white space in file names (as mentioned by Don Cragun), this

ls -l | tr -s " " " " | cut -d" " -f 1,3,4,9

might do. With spaces in there, try

...,9-

Not sure why you need the .tsv resulting file name?

1 Like

I'm myself not sure why do I need this, perhaps because of mentioning of .tsv in this tutoring course in a chapter about tr command where it's explained how to turn commas into spaces by utilizing tr , thus making .tsv (tab separated values) file of .csv ( comma separated values) file.
But since it's not so important what type of text file come into play, yeah, you're right.

If the idea is just to use tr to translate ls -l output spaces and tabs separating fields into single tab characters, you can try:

ls -l|tr -s '[:blank:]' '\t'|cut -f 1,3,4,9

which should do what you want as long as none of your filenames contain whitespace characters (i.e., spaces, tabs, or newlines). But, stat might be more reliable and just needs one command instead of a three stage pipeline:

stat -f '%Sp%t%Su%t%Sg%t%N' *

which should do what you want unless you have a lot of files in your directory with enough long filenames to overflow ARG_MAX limits.

And, if you could have large numbers of files some of which have names that contain space or tab characters (but not newlines) you could always feed the ls output through sed :

ls -l|sed 's/\([^[:blank:]]*\)[[:blank:]]*[0-9]*[[:blank:]]*\([^[:blank:]]*\)[[:blank:]]*\([^[:blank:]]*\)\([[:blank:]]*[^[:blank:]]*\)\{4\} /\1        \2      \3      /'

where those are literal tab characters after the \1 , \2 , and \3 in the replacement text of the substitute command to get exactly what you want no matter how many files are present in the directory.

Note that in all of these I used the blank character class instead of just using a space character in these patterns and BREs because I'm not sure whether ls ever uses tab characters to reduce the number of characters it writes while lining up output fields.

With a while loop:

ls -l | while read perm _ user group _ _ _ _ fname; do printf -- "$perm $user $group $fname\n"; done

Nice. This also works as long as there are no <newline> characters in any of the filenames in the current directory (and there are no <percent-sign> characters in any of the filenames). You can get rid of the <percent-sign> problem by changing the printf command in the loop to:

printf '%s %s %s %s\n' "$perm" "$user" "$group" "$fname"

if you want <space>s between fields or to:

printf '%s\t%s\t%s\t%s\n' "$perm" "$user" "$group" "$fname"

if you want <tab>s between fields.