gpt4 book ai didi

linux - 如何在没有开关 -e 的情况下找到 "echo"语句并在 Unix 中替换 "echo -e"

转载 作者:太空宇宙 更新时间:2023-11-04 12:30:52 26 4
gpt4 key购买 nike

我需要修改我所有的 unix shell 脚本、所有出现的地方以及当前目录和子目录中的所有文件,如下所示:

$ cat test.txt  ## original input file
echo "\nHello\n\tWorld 1"
echo "OK"
echo -e "\nHello\nWorld 2"
echo "OK!OK!!"
echo "Hello\nWorld 3"

修改为:

$ cat test.txt  ## desired form of file post-update
echo -e "\nHello\n\tWorld 1"
echo "OK"
echo -e "\nHello\nWorld 2"
echo "OK!OK!!"
echo -e "Hello\nWorld 3"

更多详情:

  1. echo "\n...\t..."(第 1 行和第 5 行,其中包含反斜杠字符串但不包含“-e”)到 echo -e "\n...\t..."

  2. 来自echo -e "\n...\t.."(第3行,不应该再加一个“-e”,已经有了,不需要修改这一行)

  3. 来自 echo "...."(第 2 和 4 行)- 无需更改,因为这些行不包含任何反斜杠字符。

    <

需要在所有文件语句的所有出现处用echo -e 替换echo:

  • 如果“echo statements”包含任何反斜杠字符但没有带开关的“-e”。

无需更换:

  • 如果 echo 语句包含任何反斜杠字符但已经是 echo -e,则无需更改
  • 如果“echo”语句不包含任何反斜杠字符,则无需添加 -e - 因此无需更改。

我试过:

$ grep -R "echo.*""\.*\\n.*" *| grep -v "echo.*-e" | sed 's/echo/& -e/g'

输出:

test.txt:echo -e "\nHello\n\tWorld 1"
test.txt:echo -e "Hello\nWorld 3"

它只显示要修改的行,而不是修改脚本。

请有人帮助我。

最佳答案

初始警告

请注意,如果使用足够有趣/复杂的语法,下面的代码将无法正常运行——例如,命令替换中的 echo;字符串中的那些稍后被 eval 编辑;复合命令;命令从它们的参数中拆分成多行;等等。出于这个原因,我强烈建议手动检查更改并手动合并它们(使用诸如git add -p之类的工具应该内容在修订控制中,或者vimdiff 或一般类似的)。


按字面要求

rewrite_echos() {
has_echo_re='((^|;|&)[[:space:]]*)echo([[:space:]])(.*)$'
has_echo_e_re='(^|;|&)[[:space:]]*echo[[:space:]]+-n?en?[[:space:]]+'

while IFS= read -r line; do
[[ $line =~ $has_echo_re ]] || { printf '%s\n' "$line"; continue; }
prefix=${BASH_REMATCH[1]}; suffix_chr=${BASH_REMATCH[3]}; content=${BASH_REMATCH[4]}

[[ $line =~ $has_echo_e_re ]] && { printf '%s\n' "$line"; continue; }
[[ $content = *"\\"* ]] || { printf '%s\n' "$line"; continue; }
printf '%secho -e%s\n' "$prefix" "${suffix_chr}${content}"
done
}

运行为:

rewrite_echos <test.txt

正确发出:

echo -e "\nHello\n\tWorld 1"
echo "OK"
echo -e "\nHello\nWorld 2"
echo "OK!OK!!"
echo -e "Hello\nWorld 3"

更正确:使用 printf 而不是 echo

请求的 转换不同,下面给出的转换生成适用于所有 POSIX 兼容 shell 的输出。

rewrite_echos() {
has_echo_re='((^|;|&)[[:space:]]*)echo([[:space:]])(.*)$'

while IFS= read -r line; do
[[ $line =~ $has_echo_re ]] || { printf '%s\n' "$line"; continue; }
prefix=${BASH_REMATCH[1]}; suffix_chr=${BASH_REMATCH[3]}; content=${BASH_REMATCH[4]}

[[ $content = *"\\"* ]] || { printf '%s\n' "$line"; continue; }
if [[ $content =~ ^-e[[:space:]] ]]; then
printf $'%sprintf \'%%b \'%s && printf \'\\\\n\'\n' "$prefix" "${suffix_chr}${content#-e[[:space:]]}"
else
printf $'%sprintf \'%%b \'%s && printf \'\\\\n\'\n' "$prefix" "${suffix_chr}${content}"
fi
done
}

关于linux - 如何在没有开关 -e 的情况下找到 "echo"语句并在 Unix 中替换 "echo -e",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43334487/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com