I question on a bash script and filename spaces...
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
So I'm thinking of using this script(the one you just posted, thank you)
Code:
for f in "$(find . -type f -name "*.php")";do
sed -e '/<\/body>/,$d' < $f > temp2.txt
cat string >> temp2.txt
grep '</body>' $f | head -1 >> temp2.txt
sed -e '1,/</body>/d' < $f >> temp2.txt
mv temp2.txt $f
done
But I still get each $f to be printed as a separate word. For example, the filename Star Quest.php will be printed as $f = Star and the next $f = Quest.php
You'd have to show us the entire process you run in the console. to figure out WHERE the problem with $f is occurring. But I do notice one thing up there in Post#3, and that is you are using a slash "/" as the sed special character (the field separator, so to speak) but the LHS (the regex) also contains a slash "/" which is probably causing sed to screw up. You want to use a different field separator for sed, and/or escape the slashes in the LHS.
Anyhow, please show us what you see exactly in the console, when you run the commands.
I think the problem here is that the quotes in red make the output of find to be interpreted as a single string (newlines included). I don't really know why, but I found that a reliable solution in bash is process substitution, as in:
Code:
while read f
do
ls -l "$f"
done < <(find . -type f -name "*.php")
this does not spawn a sub-process (as a pipe would do) and let you manage spaces properly. Again, I don't know why, but it works!
@ colucix -- cool, remains to be seen if this will work for the OP -- good call about the quotes; maybe we're not supposed to know why it works, if it does
One thing I'm leery of, is the "< <(..." construct. That doesn't always work, but on that, I do not know why.
@ konsolebox: great! Your example made me think of the reason why process substitution works in the code above. Indeed process substitution uses file descriptors to send its output to another process, so that the command
Code:
$ echo <(:)
/dev/fd/63
equals to passing a filename to echo: it just displays the filename as any other string passed as argument.
In the while loop discussed above, the process substitution feeds a file descriptor and its content is then passed to the loop through the input redirection. We can do the same with a real file and the result is the same (the loop over filenames with blank spaces works as expected) for example
Code:
$ cat testfile
Another Quest.php
Star Quest.php
$ while read f
> do
> ls -l "$f"
> done < testfile
-rw-r--r-- 1 alex users 0 2010-01-16 18:00 Another Quest.php
-rw-r--r-- 1 alex users 0 2010-01-16 18:00 Star Quest.php
process substitution just let us avoid the creation of a temporary file containing the result of the the find command. The read built-in does the rest, since it reads the input one line at a time and assigns the content of the entire line to the shell variable "f", blank spaces included.
Instead the for loop doesn't work since it takes the values from a list of arguments and every blank space in the list is interpreted as a field separator. In theory the for loop would work if we could do this:
Code:
for f in "Another Quest.php" "Star Quest.php"
> do
> ls -l "$f"
> done
-rw-r--r-- 1 alex users 0 2010-01-16 18:00 Another Quest.php
-rw-r--r-- 1 alex users 0 2010-01-16 18:00 Star Quest.php
but obviously a string containing double quotes at the right places is difficult to obtain from a command (not to mention it would be a waste of time, since we have the other methods cited above).
In summary it is the read statement that does the trick, not the process substitution. I can book a room in clinic, now!
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.