This question already has an answer here:

I am looping through folders, opening a file within the folder with the same name, and doing some manipulation.

I'm using sed to manipulate a line:

sed "1s/Log R Ratio/$SAMPLE.LRR/" $FILE

where $FILE is a file with 1+ spaces in the name. Example:

NAT062813_Batch A_1_TR27GD1_CytoScanHD_NL_092913/NAT062813_Batch A_1_TR27GD1_CytoScanHD_NL_092913.txt 

Is there a way (without going through and renaming things) to use sed with these files? I tried putting quotes around $FILE, but that just printed it out.

marked as duplicate by Gilles, Scott, cuonglm, muru, Anthon Dec 22 '15 at 5:53

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 1
    What kind of quotes did you try? "$FILE" or '$FILE'? – steeldriver Dec 21 '15 at 6:53
  • You also want to watch it if your $SAMPLE variable contains any / characters (or & or `). And, you might want to try embedding the whole sed` command in an -exec operator to the find command rather than looping by hand. – Wildcard Dec 21 '15 at 6:56
  • I only tried double quotes. I'll try singles. @Wildcard I'm new to writing shell scripts. Can you give an example of this? I was under the impression that a for loop is better (speedier) than find. – Gaius Augustus Dec 21 '15 at 16:25
  • There's no problem with using a for loop to iterate through files, actually. The big anti-pattern is using a for loop to iterate through lines of a file; see the question I linked to from my answer about shell loops for processing text. – Wildcard Dec 21 '15 at 16:42

Rereading your question, I think you are just missing the -i option to sed. That is the option that makes sed edit the file in place rather than printing the results to standard output.

Note that it is a very good idea to test your sed command before using the -i switch, as there is no "undo" command if you get it wrong.

So, for example, if you run sed 's/old/new/' myfile, you will see the contents of myfile printed out on your terminal with the first instance of old on each line replaced with new. If you run sed -i 's/old/new/' myfile, you won't see anything printed out—myfile will be (irrevocably) edited in place.

You can also use, for example, -i.bak instead of -i, which will cause the original file to be saved as myfile.bak and the edited file to appear as myfile. (You can define whatever extension you want instead of .bak and it doesn't need to start with a dot, but .bak is conventional to use for this purpose.)

Quotes around your space-containing filename is a separate issue and the answer to that is simple—use double quotes to get variable expansion without word splitting. So if you have a variable filenamevariable="My file name which contains spaces", you need to refer to it like so: sed 's/old/new/' "$filenamevariable"

Some other recommended reading:

  • Thank you. Yes, missing the -i option for sed was the issue. And thanks for the links. I'm still not sure I understand how to do other methods to avoid loops, but I'll look into it. I do mostly R programming, which has built in methods to avoid loops...I'll have to figure this out for shell scripting. – Gaius Augustus Dec 22 '15 at 3:52
  • Again, nothing wrong with using a for loop to iterate through files, i.e. one time through the for loop to handle one file. Just avoid "one time through a for loop to handle one line of a file" and you'll be fine. ;) – Wildcard Dec 22 '15 at 4:40

Not the answer you're looking for? Browse other questions tagged or ask your own question.