为什么 cat dcmt.txt| wc -l 是错误的
你这个问题问得非常好,而且是Shell 管道/命令替换的经典坑 👍
一句话先给结论:
管道
|只会把“文本内容”传给下一个命令,不会把它当成“参数”用。
下面一步一步把你的现象拆开讲清楚。
你现在的情况在“发生什么”
1️⃣ 文件内容分别是什么
cat 1
zwfn
cat dcmt.txt
zwfn.txt
👉 dcmt.txt 里 只是一个字符串:zwfn.txt
2️⃣ 你执行的命令
cat dcmt.txt | wc -l
Shell 的理解方式是:
把 dcmt.txt 的“内容”
→ 作为标准输入(stdin)
→ 交给 wc -l
而 dcmt.txt 的内容是:
zwfn.txt
这是 一行文本,所以:
wc -l
统计的是:
👉 输入里有几行文本
结果自然是:
1
✔ 完全正常
3️⃣ 为什么没有去统计 zwfn.txt 的行数?
因为:
wc -l不会把 stdin 里的内容当成“文件名”
它只把它当成“普通文本”
也就是说,在 wc 眼里:
zwfn.txt
不是文件名,只是 9 个字符加一个换行符。
🔑 关键概念(一定要记住)
❌ 管道 | 干不了这件事
cat dcmt.txt | wc -l zwfn.txt ❌
管道 ≠ 参数传递
管道 = 标准输入传递
✅ 正确的 3 种写法
✅ 方法 1:命令替换(最常用)
wc -l $(cat dcmt.txt)
Shell 会先做这件事:
cat dcmt.txt
# 得到:zwfn.txt
然后变成:
wc -l zwfn.txt
✔ 这才是你想要的效果
✅ 方法 2:xargs(专门干“stdin → 参数”的)
cat dcmt.txt | xargs wc -l
解释:
cat dcmt.txt → 输出 zwfn.txt
xargs → 把它变成参数
wc -l zwfn.txt → 执行
✔ 非常标准的 Unix 用法
✅ 方法 3(更高级一点):while read
适合多文件的情况:
while read f; do
wc -l "$f"
done < dcmt.txt
🧠 一张“心智模型图”
记住这张对照表:
| 方式 | 传的是什么 | |
|---|---|---|
| ` | ` 管道 | 文本内容(stdin) |
$(...) |
命令结果 → 参数 | |
xargs |
文本 → 参数 |
🧩 用一句人话总结
你以为:
“cat 把文件名传过去了”实际上:
cat 只是把‘字符 zwfn.txt’当普通文本传过去了
Shell 不会自动帮你“猜这是文件名”。

浙公网安备 33010602011771号