[英]bash script input from pipe and wc -m
我有這個代碼:
#!/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
cat file.txt | cat -n - | wc -c
有效; 那么我的代碼有什么問題?
我究竟做錯了什么?
我怎樣才能讓它正常工作?
當您通過管道而不是打開文件時,不同之處在於管道stdin
或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=$1
c=$2
還要注意參數擴展"${@--}"
擴展為"$@"
或-
取決於腳本是否收到參數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.