bash 来自管道和 wc -m 的脚本输入
bash script input from pipe and wc -m
我有这个代码:
#!/bin/bash
# ~/test.sh
if [[ -p /dev/stdin ]]; then
var="-"
else
var=""
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
有效;那么我的代码有什么问题?
我做错了什么?
如何让它正常工作?
当您通过管道而不是打开文件时,不同之处在于 piped-in 或 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=%d\nc=%d\n' "$l" "$c"
第一个cat
消耗标准输入直到文件结束;然后就无法在第二个 cat
.
中再次读取相同的数据
通常的解决方法是使用临时文件;但是如果你只是想要来自 wc
的不同计数,运行 它一次并从它的输出中提取它们。
set -- $(cat -n "${@--}" | wc -l -m)
l=
c=
另请注意参数扩展 "${@--}"
如何根据脚本是否收到参数扩展为 "$@"
或 -
。
我有这个代码:
#!/bin/bash
# ~/test.sh
if [[ -p /dev/stdin ]]; then
var="-"
else
var=""
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
有效;那么我的代码有什么问题?
我做错了什么?
如何让它正常工作?
当您通过管道而不是打开文件时,不同之处在于 piped-in 或 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=%d\nc=%d\n' "$l" "$c"
第一个cat
消耗标准输入直到文件结束;然后就无法在第二个 cat
.
通常的解决方法是使用临时文件;但是如果你只是想要来自 wc
的不同计数,运行 它一次并从它的输出中提取它们。
set -- $(cat -n "${@--}" | wc -l -m)
l=
c=
另请注意参数扩展 "${@--}"
如何根据脚本是否收到参数扩展为 "$@"
或 -
。