sed: can't read : No such file or directory
I use this as str_replace for every file in folder after unzipng archive in temp folder
find "$tmp" -type f | xargs sed -i "s/${targetsubstring}/${newsubstring}/g"
but I get this error:
sed: can't read /tmp/tmp.Q18p8BRYcc/steam: No such file or directory
sed: can't read engine.txt: No such file or directory
My tmp var:
tmp=
mktemp -d
What am I doing wrong?
UPDATE
archive=`readlink -e $1` #First param is tar archive without file structure (only text files inside)
targetsubstring=$2 #Substring to replace
newsubstring=$3 #Substring to replaced by
tmp=`mktemp -d` #Create a room to unzip our archive
if [ -f "$archive" ]; #Check if archive exist
then
echo "Well done! (And yeah, I know about [ ! -f '$1' ], but where would be the fun?)" >/dev/null
else
echo "File doesn't exist! Terminating program." >&2
exit 1
fi
tar xvf "$archive" -C "$tmp" >/dev/null #Unzip archive to temp folder
find "$tmp" -type f | xargs sed -i "s/${targetsubstring}/${newsubstring}/g" #For every file do str_replace (There is a problem somwhere)
cd "$tmp"
tar -zcf "$archive" . #Zip this to original file (I don't want any folder in my tar file)
Oh dear, you're a victim of the most terrible thing in the world: you looked on the internet to find snippets of shell-scripting, you found a lot of them, but you were never told that most of them are completely broken. Most of them break if they encounter file names with spaces in them.
This is typically the case of all the scripts that parse the output of a command designated to output information readable by humans, e.g., find
or ls
.
In your case, you have the file /tmp/tmp.Q18p8BRYcc/steam engine.txt
that contains a space and that breaks your command.
Please consider using find
properly, with its -exec
switch:
find "$tmp" -type f -exec sed -i "s/${targetsubstring}/${newsubstring}/g" {} \;
In this case, find
will -exec
ute the part
sed -i "s/${targetsubstring}/${newsubstring}/g" {}
with the place-holder {}
replaced by the found file names... but replaced properly in a way it can't bbreak if the file name contains spaces, newlines or other funny symbols. Well, it might break if {}
happens to be replaced by something that starts with a hyphen (but that is unlikely, unless the variable $tmp
expands to such a thing); in this case,
sed -i "s/${targetsubstring}/${newsubstring}/g" -- {}
will do, if your sed
version supports the --
option of course.
You could replace the trailing \;
(that means end of arguments of command to execute) by +
so that sed
will be launched with as many arguments it can handle, so it will not be spawned once per file.
Yet, there's another way to use find
safely with xargs
, using the -print0
option of find
and the -0
option of xargs
:
find "$tmp" -type f -print0 | xargs -0 sed -i "s/${targetsubstring}/${newsubstring}/g"