从pipe和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作品;那么我的代码有什么问题呢?

我做错了什么?

我怎样才能使它正常工作?

当您通过管道而不是打开文件时,不同之处在于管道输入或stdin是一个流(无需重新查找即可启动(。

l=$(cat -n "$var" | wc -l)

消耗整个流来计算行数。

到达时:

c=$(cat -n "$var" | wc -m)

stdin流已经全部被先前的行计数所消耗。它已无剩余计数,因此返回0

幸运的是,wc可以在同一次运行中同时执行这两项操作,然后您可以读取这样的结果值:

#!/usr/bin/env bash
var=${1--}
if [ -p /dev/stdin ]; then
if [ $# -ge 1 ]; then
printf %s\n 'Need either stdin or filename argument (not both)!' >&2
exit 1
fi
elif [ $# -ne 1 ]; then
printf %s\n 'Need stdin or a single filename argument!' >&2
exit 1
fi
read -r l c _ < <(wc -lm -- "$var")
printf 'l=%dnc=%dn' "$l" "$c"

第一个cat消耗标准输入,直到文件结束;那么就没有办法为第二CCD_ 7再次读取相同的数据。

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

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

还要注意参数扩展"${@--}"是如何根据脚本是否接收到参数而扩展到"$@"-的。

相关内容

  • 没有找到相关文章

最新更新