Bash scripting problem: Can't get a list of all files, including hidden ones
Hi,
I'm making a bash script to search for a word recursively using grep. Problem is, I don't find a reliable way to get a full listing of files for the current dir. Cases are: Code:
for $file in `ls -a` Code:
for $file in `ls -am` Code:
for $file in ./* Code:
for $file in ./.* So, I was wondering if I could use any kind of regular expression or glob to get both hidden and unhidden filenames. Or, if there's way to make "./.*", then "./*" and the join them in one list. Or if I can make ls use other separator than a ", ". I've been googling for a looooot of time and couldn't find a solution to my problem, that's why i'm asking here. I really appreciate your help and thanks in advance pals. Cheers :D |
Quote:
Code:
find -exec grep fnord {} /dev/null \; Normally grep, when called with a single argument will just echo the matching line of text. Adding the file /dev/null as the second file means that grep will echo the file name and the matching text. Note that under gnu grep grep -r will also read through directories recursively. |
Quote:
Code:
for $file in ./* ./.* |
Quote:
Code:
#!/bin/bash |
IFS=","
for $file in `ls -am` Resetting the internal file separator temporarily should let you parse more easily. |
FYI, to get a list from ls you could have used 'ls -a1'.
|
Thank you everybody
Wow, lots of replies. I really appreciate your effort. Thank you all :)
To the point: Quote:
Quote:
Now for the ones which did work: colucix' solution did work, however, there's something I don't like about the renaming; I can't explain what, thou. This one I named b1: Code:
#!/bin/bash Code:
#!/bin/bash Now, to be honest, using "grep -r" seems to me the best and fastest way to accomplish this. My point was to try to use as few as possible commands(I don't mean number of lines, but rather the number of total "external-to-bash" commands), and this way, you use very few commands, indeed. I like the second reply solution thou, where ./.* and ./* are used, because its more "mechanical". Also, b0 is slightly faster than b1. Here: Code:
oxi@oxibox /etc $ time b0 cool Again, thank you all for your replies! Cheers! |
Quote:
|
Hi.
This may be useful to get just the filename and get it only once ... cheers, makyo Quote:
|
Quote:
Quote:
Regarding woes with spaces in file names: Do NOT put spaces in file names. Your life will be more pleasant. (I know there's "C:\Program Files\" ... oops, wrong OS ;) ). Anyway, Quote:
Anyway, if you decided not to "grep -rl", I'd use find. Code:
find -exec grep fnord {} /dev/null \; To take care of space/comma/underscore/newlines in file names, use NUL (ASCII 0) as delimiter. (There are two characters that cannot occur in a file name: NUL and slash (/). The other 254 are possible.) So: Code:
find directory -type f -print0 | xargs -0 grep -l word_to_search_for |
I second both the use grep -l & "don't put spaces in file names". I would go 1 step further & say, "change the spaces to underscores in the filenames you have":
Code:
# SpaceOut archtoad6 Feb. 2007 Code:
for F in *' '*;do mv "$F" `echo $F|tr \ _`;done Exploring "Spaced Out" Filenames For grins, I ran the following: Code:
locate \ |wc -l Next I filtered out the files salvaged from an old "Winders" drive: 1671, no where near as bad. Then I filtered out a dir. containing mostly stuff from clueless "Winders" sites & software: 202, getting better. Last I ran: Code:
locate \ |grep -v "$CLUELESS\|\.html\|\.htm\|\.jpeg\|\.jpg" |wc -l I ran Code:
locate \ |grep -v "$CLUELESS\|\.html\|\.htm\|\.jpeg\|\.jpg" |less -SN |
Quote:
Either: for file in ./* ./.* Or: shopt -s dotglob for file in ./* |
This kind of question has been answered a few times before. I know, because I've written a number of them ;)
Try this: contents of simple_script.bash: Code:
#!/bin/bash at the command prompt: Code:
$ chmod u+x simple_script.bash Code:
for filename in $( ls -1A ) ; do |
Quote:
Code:
IFS=$'\n' Quote:
Quote:
Yes, a variable containing a filename should always be quoted, but that is too late to prevent the word splitting that will already have occurred by using for filename in $( ls -lA ). Quote:
|
Quote:
Quote:
Code:
filename="my test file.txt" Quote:
Code:
IFS=${old_ifs} And just to be thorough, I used a 1 (one) in the ls command--not an l (el). Makes a difference in the output :) |
All times are GMT -5. The time now is 02:36 PM. |