sed:无法读取:没有这样的文件或目录

Joh*_*Dow 8 linux sed

在临时文件夹中解压缩存档后,我将其用作文件夹中每个文件的 str_replace

find "$tmp" -type f | xargs sed -i "s/${targetsubstring}/${newsubstring}/g"
Run Code Online (Sandbox Code Playgroud)

但我收到此错误:

sed: can't read /tmp/tmp.Q18p8BRYcc/steam: No such file or directory
sed: can't read engine.txt: No such file or directory
Run Code Online (Sandbox Code Playgroud)

我的 tmp 变量:

tmp=mktemp -d

我究竟做错了什么?

更新

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)
Run Code Online (Sandbox Code Playgroud)

gni*_*urf 18

哦,亲爱的,你是世界上最可怕事情的受害者:你在互联网上寻找 shell 脚本的片段,你找到了很多,但你从来没有被告知它们中的大多数都被完全破坏了。如果遇到其中包含空格的文件名,它们中的大多数都会中断。

这通常是解析指定为输出人类可读信息的命令的输出的所有脚本的情况,例如,findls

在您的情况下,您的文件/tmp/tmp.Q18p8BRYcc/steam engine.txt包含一个空格并且会破坏您的命令。

请考虑find 正确使用,及其-exec开关:

find "$tmp" -type f -exec sed -i "s/${targetsubstring}/${newsubstring}/g" {} \;
Run Code Online (Sandbox Code Playgroud)

在这种情况下,find-execute 部分

sed -i "s/${targetsubstring}/${newsubstring}/g" {}
Run Code Online (Sandbox Code Playgroud)

{}找到的文件名替换占位符......但如果文件名包含空格,换行符或其他有趣的符号,则以一种无法中断的方式正确替换。好吧,如果{}碰巧被以连字符开头的东西替换,它可能会中断(但这不太可能,除非变量$tmp扩展为这样的东西);在这种情况下,

sed -i "s/${targetsubstring}/${newsubstring}/g" -- {}
Run Code Online (Sandbox Code Playgroud)

可以,如果您的sed版本--当然支持该选项。

您可以替换尾随\;(这意味着要执行的命令的参数结束),+以便sed使用它可以处理的尽可能多的参数启动它,因此每个文件不会产生一次。


然而,还有另一种find安全使用with 的方法xargs,使用-print0选项 offind-0选项xargs

find "$tmp" -type f -print0 | xargs -0 sed -i "s/${targetsubstring}/${newsubstring}/g"
Run Code Online (Sandbox Code Playgroud)