在bash中:
我正在尝试合并目录中的所有文件,然后使用一个命令计算所有行的总数。我意识到我可以使用 |通过管道传输两个命令:
! cat /data/files *.txt >> mergedfile.txt | wc -l ~/data/files/mergedfile.txt
然而,这似乎不起作用。我正在使用 bash 并在 iPython 中运行(因此前面有 !)。
答案1
你的问题有点乱:
- 你用它
!
来代表你的 shell 提示符吗?这很不典型。 - 你说的是目录
.txt
中的所有文件/data/files
吗?要做到这一点,你应该说/data/files/*.txt
。如果您的意思是其他意思/data/files *.txt
,请解释一下。 >> mergedfile.txt
将要附加文件到mergedfile.txt
,如果它已经存在。那是你要的吗?如果您想要类似的东西,您应该在问题中这么说。
无论如何,正如所说通过箭头在评论中,简单、明显的解决方案是将 替换|
为 a ;
,如下所示:
$ cat /data/files/*.txt >> mergedfile.txt; wc -l mergedfile.txt
笔记:
- 正如我上面所说, 如果文件已经存在,
>>
则将其追加。mergedfile.txt
如果您想忽略(丢弃) 的任何先前内容mergedfile.txt
,请使用>
代替>>
。 - 如果您要多次引用同一个文件,则每次都应该以相同的方式执行。一次使用相对路径名,下一次使用绝对路径名会造成混乱且容易出错。 (您可能希望通过将文件名分配给变量来简化事情。)
在上面的基础上稍作改进的是:
$ cat /data/files/*.txt > mergedfile.txt && wc -l mergedfile.txt
用&&
代替;
.这会导致wc -l
仅在命令成功时才执行该命令cat
。
上述每个命令行都被描述为一个“命令列表”,包含两个“管道”(尽管不涉及实际的管道)。如果您想将其作为单个“管道”来执行,请执行以下操作:
$ cat /data/files/*.txt | tee mergedfile.txt | wc -l
计算行数当它连接文件时,
无需读取输出文件。如果您想附加到现有的mergedfile.txt
,请使用tee -a
.
答案2
它应该是:
! cat /data/files/*.txt >> mergedfile.txt && wc -l /data/files/mergedfile.txt
您的命令由两个命令组成 - 第一个是cat
,通过重定向输出到文本文件 - 第二个是计算结果文件的长度
如果第一个命令成功,这两个命令需要按顺序运行。所以你就用&&
链吧。在stdout
被cat
重定向到之后mergedfile.txt
,该命令cat
不会生成stdout
管道到wc
。所以使用|
那里是错误的。
或者, 你可以做:
! cat /data/files/*.txt | wc -l
这更简洁并且避免使用临时文件。这里的输出cat
被直接发送到wc
计数。
笔记,第一种使用临时文件的方法有很多缺点:
- 您需要
mergedfile.txt
在执行之前清空该文件。如果您开始时工作目录中没有该文件,那也没关系。但很常见的是,您首先尝试了一些命令(例如您使用了错误的命令),然后忘记清空临时文件并运行正确的命令。它仍然会导致错误的答案。事实上,如果所有行都在 中/data/files/*.txt
,您可以简单地使用>
代替>>
。它会首先清空文件。 - 在命令执行期间,临时文件可能会被其他用户更改,或者当您想要并行执行某些操作时由您自己更改。
此外:如果以后需要mergedfile.txt
使用,可以使用以下命令tee
来复制输出:
! cat /data/files/*.txt | tee mergedfile.txt | wc -l
tee
将其放入stdin
其中并将mergedfile.txt
其复制到stdout
。