来自管道和wc -m的bash脚本输入

问题描述

我有代码

#!/bin/bash
# ~/test.sh
if [[ -p /dev/stdin ]]; then
var="-"
else
var="$1"
fi
l=$(cat -n "$var" | wc -l)
c=$(cat -n "$var" | wc -m)
echo l=$l
echo c=$c

如果我跑步:

$ ./test.sh file.txt
l=73
c=4909 # it is correct

但如果

cat file.txt | ./test.sh
l=73
c=0    #why i have 0???

我不明白为什么我有c = 0

cat file.txt | cat -n - | wc -c有效;那么我的代码有什么问题?

我在做什么错了?

我如何使其正常工作?

解决方法

当您通过管道传输而不是打开文件时,不同之处在于,管道传输或kivy 1.11.1是流(无回溯开始)。

kivy.deps.sdl2 2.0.0

使用整个流来计数行。

到达时:

stdin

l=$(cat -n "$var" | wc -l) 流已被先前的行计数全部消耗。它没什么可剩下的,因此返回c=$(cat -n "$var" | wc -m)

幸运的是,stdin可以在同一运行中同时完成这两个操作,然后您可以读取如下结果值:

0
,

第一个cat使用标准输入,直到文件结束;这样就无法在第二个cat中再次读取相同的数据。

通常的解决方案是使用一个临时文件。但是如果您只想从wc中获得不同的计数,请运行一次并从其输出中提取它们。

set -- $(cat -n "${@--}" | wc -l -m)
l=$1
c=$2

还请注意,取决于脚本是否接收到参数,参数扩展"${@--}"如何扩展为"$@"-