我有一个代码,用于更改空格划分的数据库的第一部分:
if [[ "$(cut -d ' ' -f 1 commandnames.txt | grep -F "$2")" == "" ]] ; then
while read -r name rest; do
if [[ "$1" == "$name" ]]
then echo "$2 $rest"
else echo "$name $rest"; fi
done < commandnames.txt > commandnames.txt
echo "Renamed $1 to $2."
fi
但是,> commandnames.txt
不起作用,而是清除文件。当输出要stdout时,它可以正常工作。我尝试将while
循环放置,直到stdout重定向为子壳,但似乎没有用。关于为什么不起作用的任何想法?
执行
while read -r name rest; do
...
done < commandnames.txt > commandnames.txt
这就是发生的事情:
-
< commandnames.txt
:打开" commandnames.txt"用于阅读 -
> commandnames.txt
:打开" commandnames.txt"进行编写和截断。 -
while read -r name rest
:一次阅读一行直到stdin为空
由于步骤2截断了文件,因此循环运行0次,因此没有什么可写的。因此,文件为空。
修复程序很简单:避免在阅读输入之前删除输入。
您可以通过写入临时文件来做到这一点,然后在完成后覆盖原件:
while read -r name rest; do
...
done < commandnames.txt > tmpfile && mv tmpfile commandnames.txt
但是,
> commandnames.txt
不起作用,而是清除 文件。
说 > outfile
会 truncate 1 要开头的文件。
因此,您从同一文件中读取的尝试不会产生结果。
将输出重定向到另一个文件和mv
或cp
,以后可能是。
1 引用手册(重点是我的):
输出的重定向会导致该文件的名称来自 将要在文件描述符上写作的单词扩展 n 或 如果未指定 n ,则标准输出(文件描述符1)。如果是 文件不存在它是创建的;如果确实存在,则将其截断为 零大小。
您不会在没有某种临时存储的情况下做到这一点。
如果您100%确定您的commandnames.txt文件永远不会太大,则可以将文件读取到变量中,然后解析变量的内容
GV_LINES=$(cat test_lines.txt)
while read LV_LINE
do
echo "${LV_LINE}_suffix"
done <<< "${GV_LINES}" > test_lines.txt
其他查看mktemp或tempfile命令以创建临时文件