我需要修改我的所有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"
更多详情:
从echo "\n...\t..."
(行:1和5,其中包含反斜杠字符串但不包含“-e”)到echo -e "\n...\t..."
从
echo -e "\n...\t.."
(第3行,不应再添加一个“-e”,它已经存在,无需修改此行)
来自echo "...."
(第2行和第4行) - 无需更改,因为这些行不包含任何反斜杠字符。
需要在所有文件语句中的所有匹配项中将echo
替换为echo -e
:
无需替换:
echo
语句包含任何反斜杠字符但已经echo -e
,则无需更改-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"
它只显示要修改的行但不修改脚本。
请有人帮助我。
答案 0 :(得分:0)
请注意,如果使用足够有趣/复杂的语法 - echo
s命令替换,则下面的行为不会很好;那些后来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
}