簡體   English   中英

從管道和 wc -m 輸入的 bash 腳本

[英]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有效; 那么我的代碼有什么問題?

我究竟做錯了什么?

我怎樣才能讓它正常工作?

當您通過管道而不是打開文件時,不同之處在於管道stdinstdin是一個流(不返回開始)。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM