我正在运行命令以将,
文件替换为换行符
echo `tr ',' '\n' < file.txt` > file.txt
该命令正在转换
a,b,c
至
a b c
而不是将其转换为
a
b
c
谁能向我解释为什么会发生并解决这个问题?
首先,运行一个将输入和输出重定向到同一个文件的命令是危险的。正如您所看到的,它可能会起作用,但它可能会在您尝试读取文件时破坏文件的内容,具体取决于事情发生的顺序。
为了避免这个问题,让我们简化命令:
$ cat file.txt
a,b,c
$ tr , '\n' < file.txt
a
b
c
所以tr
命令本身正在按您的预期工作。现在让我们尝试回显输出:
$ echo `tr , '\n' < file.txt`
a b c
shell 执行命令并将其输出用作echo
-- 但输出被分割成由空格分隔的单词(包括换行符)。
如果您使用 sh、bash 或类似的 shell,则可以通过引用以下参数来避免这种情况:
$ echo "`tr , '\n' < file.txt`"
a
b
c
如果你的 shell 支持它(大多数都支持),你可以使用$(...)
而不是反引号:
$ echo "$(tr , '\n' < file.txt)"
a
b
c
我发现它更容易阅读,因为您可以轻松地区分结构的开头和结尾;它也可以嵌套。
最后,至少对于您正在做的事情,使用echo
. 这是我的做法:
tr , '\n' < file.txt > $$ && mv $$ file.txt
这会翻译 的内容file.txt
,将输出写入临时文件($$
是当前 shell 的进程 ID,便于生成临时文件名)。然后它将临时文件重命名为file.txt
-- 但前提是第一个命令成功。如果出现问题,可以避免破坏您的输入文件。
这可能是您正在寻找的。
tr ',' '\n' < file.txt > tempFile.txt
mv tempFile.txt file.txt
cat file.txt | tr "," "\n"
然后可以将其重定向到您的文件(通过Keith 在上面的评论中提到的中间 tmp 文件)
或许这
sed -i 's , \n g' file.txt