在bash脚本中重定向输出时如何避免使用特殊字符

Not*_*ber 6 bash

当将输出从bash脚本重定向到文件时,我在文件中得到特殊字符.例如,

for file in *; do echo $file; done > output.txt
Run Code Online (Sandbox Code Playgroud)

那么如果我cat output.txt

cat output.txt
Run Code Online (Sandbox Code Playgroud)

我明白了

file1.txt
file2.txt
file3.txt
output.txt
Run Code Online (Sandbox Code Playgroud)

但是在编辑文件时,我看到了这个:

^[[0m^[[0mfile1.txt
^[[0m^[[0mfile2.txt
^[[0m^[[0mfile3.txt
^[[0m^[[0moutput.txt
Run Code Online (Sandbox Code Playgroud)

我如何避免那些讨厌的角色?


解:

我在.bashrc中有以下行:

trap 'echo -ne "\e[0m"' DEBUG
Run Code Online (Sandbox Code Playgroud)

通过删除它,我解决了这个问题.

感谢大家的帮助.

tha*_*guy 5

这些是ANSI转义码,用于格式化终端中的文本.而不是试图删除它们,你应该首先防止它们被写入.

你确定你从你发布的确切代码中得到了这个吗?如果是这样,您的文件实际上在您的名称中包含这些字符,您只需重命名它们即可.

更常见的方法是使用输出ANSI转义序列的工具.这是显示相同问题的可重现方式:

ls --color=always > file
Run Code Online (Sandbox Code Playgroud)

如果您发布的代码是一个未经测试的示例,您应该查找负责ANSI代码的工具并使其停止(尤其要确保您没有循环输出ls).

以下是您所看到的问题的一个示例,其中touch包含一些使用ANSI转义意外创建文件名的进程/脚本的替身:

# Reproduce the problem
$ touch $'\x1B[0m\x1B[0mfile.txt'

# Symptoms of the problem
$ ls *.txt
?[0m?[0mfile.txt

$ for f in *.txt; do echo "$f"; done
file.txt

$ for f in *.txt; do echo "$f"; done | cat -v
^[[0m^[[0mfile.txt

# Fix the problem by renaming the bad files
$ crud=$'\x1B[0m'; for f in *"$crud"*; do mv "$f" "${f//$crud/}"; done

# Now works as expected
$ ls *.txt
file.txt

$ for f in *.txt; do echo "$f"; done
file.txt

$ for f in *.txt; do echo "$f"; done | cat -v
file.txt
Run Code Online (Sandbox Code Playgroud)