Reputation: 1533
I have found some similar questions here but not this specific one and I do not want to break all my files. I have a list of files and I simply need to replace all spaces with underscores. I know this is a sed
command but I am not sure how to generically apply this to every file.
I do not want to rename the files, just modify them in place.
Edit: To clarify, just in case it's not clear, I only want to replace whitespace within the files, file names should not be changed.
Upvotes: 0
Views: 5232
Reputation: 772
This is a 2 part problem. Step 1 is providing the proper sed command, 2 is providing the proper command to replace all files in a given directory.
Substitution in sed commands follows the form s/ItemToReplace/ItemToReplaceWith/pattern
, where s
stands for the substitution and pattern
stands for how the operation should take place. According to this super user post, in order to match whitespace characters you must use either \s
or [[:space:]]
in your sed command. The difference being the later is for POSIX compliance. Lastly you need to specify a global operation which is simply /g at the end. This simply replaces all spaces in a file with underscores.
Substitution in sed commands follows the form s/ItemToReplace/ItemToReplaceWith/pattern
, where s
stands for the substitution and pattern
stands for how the operation should take place. According to this super user post, in order to match whitespace characters you must use either just a space in your sed command, \s
, or [[:space:]]
. The difference being the last 2 are for whitespace catching (tabs and spaces), with the last needed for POSIX compliance. Lastly you need to specify a global operation which is simply /g at the end.
Therefore, your sed command is
sed s/ /_/g FileNameHere
However this only accomplishes half of your task. You also need to be able to do this for every file within a directory. Unfortunately, wildcards won't save us in the sed command, as * > *
would be ambiguous. Your only solution is to iterate through each file and overwrite them individually. For loops by default should come equipped with file iteration syntax, and when used with wildcards expands out to all files in a directory. However sed's used in this manner appear to completely lose output when redirecting to a file. To correct this, you must specify sed with the -i
flag so it will edit its files. Whatever item you pass after the -i
flag will be used to create a backup of the old files. If no extension is passed (-i ''
for instance), no backup will be created.
Therefore the final command should simply be
for i in *;do sed -i '' 's/ /_/g' $i;done
Which looks for all files in your current directory and echos the sed output to all files (Directories do get listed but no action occurs with them).
Upvotes: 1
Reputation: 1533
Well... since I was trying to get something running I found a method that worked for me:
for file in `ls`; do sed -i 's/ /_/g' $file; done
Upvotes: 0
Reputation: 11435
find . -type f -exec sed -i -e 's/ /_/g' {} \;
find
grabs all items in the directory (and subdirectories) that are files, and passes those filenames as arguments to the sed
command using the {} \;
notation. The sed
command it appears you already understand.
if you only want to search the current directory, and ignore subdirectories, you can use
find . -maxdepth 1 -type f -exec sed -i -e 's/ /_/g' {} \;
Upvotes: 2