1

I am starting with a file containing a list of hundreds of files (full paths) in a random order. I would like to list the details of the ten latest files in that list. This is my naive attempt:

$ ls -las -t `cat list-of-files.txt` | head -10 

That works, so long as none of the files have spaces in, but fails if they do as those files are split up at the spaces and treated as separate files. File "hello world" gives me:

ls: hello: No such file or directory ls: world: No such file or directory 

I have tried quoting the files in the original list-of-files file, but the here-document still splits the files up at the spaces in the filenames, treating the quotes as part of the filenames:

$ ls -las -t `awk '{print "\"" $0 "\""}' list-of-files.txt` | head -10 ls: "hello: No such file or directory ls: world": No such file or directory 

The only way I can think of doing this, is to ls each file individually (using xargs perhaps) and create an intermediate file with the file listings and the date in a sortable order as the first field in each line, then sort that intermediate file. However, that feels a bit cumbersome and inefficient (hundreds of ls commands rather than one or two). But that may be the only way to do it?

Is there any way to pass "ls" a list of files to process, where those files could contain spaces - it seems like it should be simple, but I'm stumped.

1
  • Thank you all - I have a few answers here that work, and am using Marco's version. I'm sure the xargs method could run with some tweaks, and I'll look into that for the longer term. All help much appreciated. Commented Jan 5, 2011 at 10:23

4 Answers 4

6

Instead of "one or more blank characters", you can force bash to use another field separator:

OIFS=$IFS IFS=$'\n' ls -las -t $(cat list-of-files.txt) | head -10 IFS=$OIFS 

However, I don't think this code would be more efficient than doing a loop; in addition, that won't work if the number of files in list-of-files.txt exceeds the max number of arguments.

Sign up to request clarification or add additional context in comments.

3 Comments

My goodness - I never knew that. This works a treat :-) No changes to my existing code whatsoever - I just set IFS in the script that does the listing.
@Jason: Then you should probably mark this as the accepted answer. I'm giving it a +1, myself.
Ah - click the tick ;-) Been looking at how to accept an answer and just couldn't see the wood for the trees.
2

Try this:

xargs -a list-of-files.txt ls -last | head -n 10 

1 Comment

I don't have a "-a" option on my version of xargs. I have tried piping the source file into xargs, but that gives me the same issue - filenames split at spaces.
1

I'm not sure whether this will work, but did you try escaping spaces with \? Using sed or something. sed "s/ /\\\\ /g" list-of-files.txt, for example.

2 Comments

The spaces still seem to be sucked in: ls: hello\: No such file or directory \nls: world: No such file or directory
Hmm. Well, it was worth a try, I guess. marco's solution seems like the way to go, I'm upvoting it. :)
1

This worked for me:

xargs -d\\n ls -last < list-of-files.txt | head -10 

1 Comment

So xargs isn't running ls multiple times - it just runs it once, but handles passing the space-containing parameters better than a here-document. I don't seem to have the "-d" option on my xargs (GNU xargs version 4.1.20) but I'll follow this approach up.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.