我尝试创建rev
一个文件然后将其传输到管道cat > same_file
但它变成了一个空白文件。
当我尝试时rev file.txt | cat > file2.txt && mv file.txt file2.txt;
,它起作用了。
甚至rev file.txt | cat >> file.txt;
起作用了。
但当我尝试时rev file.txt | cat > file.txt
它失败了。
答案1
在这种情况下,您需要掌握的两种重定向方式(> 和 >>)的基本内容是:
>
重定向和覆写它所指向的信息。通过管道“|”接收任何信息时都会发生这种情况
>>
重定向和连接指向它所指向的信息。当通过管道“|”接收任何信息时,都会发生这种情况
在这两种情况下,如果文件不存在,则会创建该文件。只有在“>>”上,如果您再次对同一文件运行它,信息才会连接起来。使用“>”,您只需覆盖第一次运行时所做的一切。
但是,当使用相同的输入文件作为输出文件时,情况就不同了。在这种特殊情况下,如果您使用“>”,您将删除“输入”部分需要解析的信息,因为输出文件将“覆盖它”。因此:
rev file.txt | cat > file.txt
“慢动作解释”中实际发生的情况是:
rev
准备反转的内容file.txt
并发送到管道- 当
rev
正在将信息发送到管道时,管道会将其直接传输到cat
。 cat
在接收信息时,它会自动将其应用于所设置file.txt
的内容。- 这里的关键词是“while”,因为所有事情都是同时发生的。请参阅下面 Emil 的精彩评论,以更深入地了解这一部分。
cat
不会等待rev
来传输整个文件。它会在收到第一部分信息后立即启动,这意味着,根据您使用的符号,它会打开到 的连接file.txt
。- 在这种情况下,由于您使用了>代替>>,shell 将截断输出文件,这意味着它将打开并明确
file.txt
等待新信息到达时,它会保留信息。>>它将打开一个连接file.txt
并等待最后一行检测到的新信息。 - 由于信息已经
file.txt
清除>,rev
会尝试完成它的工作但却一无所获,因为cat
为了准备新的信息而删除了所有内容。
那么,为什么读完上述内容后,其他方法仍然有效呢?原因如下:
rev file.txt | cat > file2.txt && mv file.txt file2.txt
在这里你通过管道将信息发送给 cat其他文件。在这种情况下,处理后的输入文件与file.txt
输出文件不同file2.txt
。之后,您实际上是用 覆盖整个文件,因此删除了由 进行的所有处理。基本上,整行可以简化为 ,因为它在做同样的事情,因为最后丢失了并被命令覆盖。file2.txt
file.txt
cat
cp file.txt file2.txt
file2.txt
rev
mv
rev file.txt | cat >> file.txt
在这种情况下,你连接信息到同一个文件。因此,它只是打开与该文件的连接,但不会像单个文件那样删除信息>最终的结果应该是,原始信息加上反转后的信息。
答案2
答案3
>
是一个重定向器(操作符),将输出发送到其他东西
(下一个命令的输入、打印机..)
在您的情况下,输出将转到一个文件file.txt
,如果此文件已存在,则将其覆盖,如果不存在,则创建。
>>
是一个附加运算符,如果file.txt
已经存在,则输出将附加到文件末尾。如果文件不存在,则创建该文件,并将输出写入新文件,与>
(重定向器)。
答案4
你可以在 Ex 模式下使用 Vim:
ex -sc '%!rev' -cx file.txt
%
选择所有行!
运行命令x
保存并关闭