LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 10-03-2010, 02:24 PM   #1
RabidRick
LQ Newbie
 
Registered: Oct 2010
Posts: 1

Rep: Reputation: 0
ls: listing filenames without directories?


So my boyfriend's GSI for one of his classes told him there's a way you can use ls (not find) to list filenames one-per-line, in BASH without including directories. I think he was either wrong or making that up. There is a way to list just the names and one per line but there aren't any arguments I can find that can be used to exclude directories.

Anyone have a clue? Here's the only way I've been able to do it thus far but apparently isn't what he meant:

Code:
IFS=', '; files=`ls -m`; for i in $files; do if [ -f $i ]; then echo $i; fi; done
That does only use ls as a command, however he said his GSI thought he could do it without all that...

Quote:
ricky@ricky-desktop:~$ ls -l
total 1376
drwxr-xr-x 2 ricky ricky 4096 2010-10-02 22:17 Azureus Downloads
drwxr-xr-x 4 ricky ricky 4096 2010-10-02 22:16 Desktop
drwxr-xr-x 2 ricky ricky 4096 2010-09-29 23:50 Downloads
-rw-r--r-- 1 ricky ricky 1384777 2010-09-05 01:32 Firefox_wallpaper.png
-rw-r--r-- 1 ricky ricky 6 2010-10-02 04:17 test
-rw-r--r-- 1 ricky ricky 6 2010-10-02 19:35 test2
Quote:
ricky@ricky-desktop:~$ ls -m1
Azureus Downloads
Desktop
Downloads
Firefox_wallpaper.png
test
test2
Quote:
ricky@ricky-desktop:~$ IFS=', '; files=`ls -m`; for i in $files; do if [ -f $i ]; then echo $i; fi; done
Firefox_wallpaper.png
test
test2
Am I missing something, here?

Thanks in advance!
 
Old 10-03-2010, 04:57 PM   #2
{BBI}Nexus{BBI}
Senior Member
 
Registered: Jan 2005
Location: Nottingham, UK
Distribution: Mageia 6, KDE Neon
Posts: 4,313

Rep: Reputation: 212Reputation: 212Reputation: 212
Could it be something like ls -1 (<-this is the number 1) */ This lists the directory contents one per line and only shows the directory name where the files reside.

Code:
ls -1 */
 
Old 10-03-2010, 08:09 PM   #3
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 374Reputation: 374Reputation: 374Reputation: 374
It's these little "puzzles" that aggravate me. The "solution" never matches the expectation you have after the initial presentation of the problem. Given that this is from an academic setting, the solution is probably not usable in any practical sense--just a curiosity.

That said, you need more information, but here are some "answers" with varying levels of cheesy-ness:

1. ls is open source--go rewrite it to exclude directories by default
2. enforce a naming scheme for your directories (e.g. "all directories must start with an underscore"). In that case, you can use the "--hide" or "--ignore" options to filter the directories from the output

more serious approaches:
3. ls can take a list of files on the command-line. So you can have a command in this form: "ls <args1> `ls <args2>`" I experimented with the -p option (which adds a trailing slash '/' to directory entries) as part of args2 and then tried --hide="*/" as part of args1, but didn't get anywhere.

4. there may be an approach with globbing in the shell. I glanced through the man page, and saw reference to using "**" and "**/" as special globs/wildcards. I didn't look that hard or experiment at all.

a non-ls-exclusive solution:
The above assumes you can only use ls, but if you can use another tool, this should work easily:
ls -l | grep -v "^d"

or the "reverse" of the same command:
ls -l | grep "^-"

As a side note, there have been a number of "how do I display directories only" types of threads in the past. You might find some inspiration in them. But most of them will probably use the pipe-into-grep solution above.

Last edited by Dark_Helmet; 10-03-2010 at 08:10 PM.
 
Old 10-04-2010, 05:53 AM   #4
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Displaying directories only is rather easy.
Code:
ls -d */
ls -d **/  #for recursive listing.  See the postscript below.
But I've tried dozens of ideas, and I'm starting to think files-only is impossible without the use of some outside tool. The best I've come up with so far is this.
Code:
ls -p | grep -v /$
Unfortunately, as Dark Helmet also discovered, ls itself seems to treat the -p backslashes independently of the --ignore or --hide options, so that's no good.

The only direction I can think to go, if there is a solution to this, is through globbing or some other path matching trickery. As a simple example, if you could be sure that files have extensions, while directories don't (a poor assumption of course), then this would work.
Code:
ls *.*
I still haven't figured out anything that will definitively exclude directories no matter what the name, however.

PS. ** is the new bash.v4 recursive listing option. It's disabled by default, so use shopt -s globstar to enable it. But I don't think it will likely have much use in this situation, unless the challenge is expanded to include recursiveness too.
 
Old 10-04-2010, 06:07 AM   #5
MrCode
Member
 
Registered: Aug 2009
Location: Oregon, USA
Distribution: Arch
Posts: 864
Blog Entries: 31

Rep: Reputation: 148Reputation: 148
Quote:
Originally Posted by Dark_Helmet
I experimented with the -p option (which adds a trailing slash '/' to directory entries) as part of args2 and then tried --hide="*/" as part of args1, but didn't get anywhere
Here's an idea: maybe make something like sed or awk clip the directories out of the ls -p output. Now, I have next to zero knowledge of awk or regex syntax, so don't ask for a cut-'n-paste command or anything...just a thought.

One thing about that: you probably wouldn't be able to preserve any color-coding (e.g. if you used ls -p --color=auto, or if you have ls aliased to ls --color=auto as I do ).
 
Old 10-04-2010, 04:59 PM   #6
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Quote:
Originally Posted by MrCode View Post
One thing about that: you probably wouldn't be able to preserve any color-coding...
Sure you could. Just use --color=always and make sure your expression is designed to deal with the embedded non-printing characters on either side of the names. It'd probably be a bit of extra work, but far from impossible.

But then again this is just another variation of what's been pointed out before; that it's possible, indeed easy, when you can use an external tool to parse the output. There are likely dozens of good solutions you could come up with using various programs. I already have some ideas about how it could be done using various shell scripting techniques.

The challenge as I see it is whether there's any way to do it using only ls, and nothing else that could be considered a command (executable or shell built-in). In other words, things like globbing and needing to have certain shell options enabled first would be acceptable, but scripting mechanisms like loops and especially test probably wouldn't. I'm starting to believe there isn't any way to do it.

On the other hand there are other questions about the challenge that are even less clear. Long format, short format, any format? Current directory only, or recursive as well? It might help if we knew exactly what the expected output would be.
 
Old 10-04-2010, 05:30 PM   #7
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 374Reputation: 374Reputation: 374Reputation: 374
Yeah, IF it's possible, it will likely depend on both ls and the shell environment.

I played with things a little more because David's post got me thinking. I combined his any my approach.

Rather than describe with words, here's what I tried:
Code:
ls -1 --hide=`ls -d */`
In other words, I thought, "if getting a directory-only listing is a simple command, is there some way it could be turned into a filter?"

Unfortunately, the "PATTERN" as described in the man page for --hide won't accept and use the ls output like we want. For this approach to work, the interior directory listing would need it's output changed to use a vertical bar between the directory names. I saw no way of convincing ls to use those bars (which would need to be escaped mind you--otherwise the shell might see them as pipes--depending on the order of expansion/inerpretation).

Also, when thinking about that, I realized (again) how the shell handles things. The fileglobbing expansion happens before ls is executed.

That makes me believe the environment is really the key as opposed to ls. So, if the original question does indeed have a solution, it's more likely the result of the shell's fileglobbing, and we've assumed bash so far. I have little experience with tcsh, but that's a possibility. tcsh is more C-like in its syntax and hence, more "familiar" especially in a computer curriculum. There's also ksh, ash, and who knows how many others. Each handles fileglobbing differently.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Spaces in Filenames and/or Directories bruceam Linux - Newbie 5 12-14-2009 10:02 AM
Listing Huge Directories Woodsman Slackware 8 12-16-2007 02:29 PM
Recursive directories listing cdog Linux - General 11 12-09-2006 07:04 AM
Listing all directories only anjanesh Linux - Newbie 5 06-20-2006 03:23 AM
Getting colored directories/filenames in the terminal Locura Slackware 10 06-26-2003 12:48 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 05:04 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration