代码之家  ›  专栏  ›  技术社区  ›  RichieHindle

在unix shell中添加一列数字

  •  172
  • RichieHindle  · 技术社区  · 15 年前

    给出了文件列表 files.txt ,我可以得到它们的大小列表,如下所示:

    cat files.txt | xargs ls -l | cut -c 23-30
    

    它产生了这样的结果:

      151552
      319488
     1536000
      225280
    

    我怎么才能拿到 全部的 在所有这些数字中?

    19 回复  |  直到 6 年前
        1
  •  350
  •   Todd Owen    10 年前
    ... | paste -sd+ - | bc
    

    是我找到的最短的(从 UNIX Command Line 博客)。

    编辑: 增加了 - 关于便携性的争论,谢谢@dogbert和@owen。

        2
  •  147
  •   Greg Reynolds    15 年前

    这里去

    cat files.txt | xargs ls -l | cut -c 23-30 | 
      awk '{total = total + $1}END{print total}'
    
        3
  •  9
  •   ALL    13 年前

    如果文件名中有空格,则cat将不起作用。这里是一个PerlOne的内衬。

    perl -nle 'chomp; $x+=(stat($_))[7]; END{print $x}' files.txt
    
        4
  •  8
  •   Barun    15 年前

    而不是使用 从的输出中获取文件大小 LS-L ,您可以直接使用:

    $ cat files.txt | xargs ls -l | awk '{total += $5} END {print "Total:", total, "bytes"}'
    

    awk将“$5”解释为第五列。这是来自 LS-L 这就提供了文件大小。

        5
  •  7
  •   Collin Anderson    11 年前
    cat files.txt | xargs ls -l | cut -c 23-30 | python -c'import sys; print sum(int(x) for x in sys.stdin)'
    
        6
  •  5
  •   om-nom-nom Dennis Williamson    11 年前

    TMTWWTDI :perl有一个文件大小运算符(-s)

    perl -lne '$t+=-s;END{print $t}' files.txt
    
        7
  •  3
  •   MichaelJones catherine    15 年前

    我会用“du”来代替。

    $ cat files.txt | xargs du -c | tail -1
    4480    total
    

    如果您只想要号码:

    cat files.txt | xargs du -c | tail -1 | awk '{print $1}'
    
        8
  •  3
  •   Andre Miller    15 年前

    如果只想在不使用awk或其他解释器的情况下使用shell脚本,则可以使用以下脚本:

    #!/bin/bash
    
    total=0
    
    for number in `cat files.txt | xargs ls -l | cut -c 23-30`; do
       let total=$total+$number
    done
    
    echo $total
    
        9
  •  3
  •   Sanjaya R    15 年前

    在KSH:

    echo " 0 $(ls -l $(<files.txt) | awk '{print $5}' | tr '\n' '+') 0" | bc
    
        10
  •  3
  •   Hugo González Monteverde    9 年前

    整个L-L和切割都很复杂 斯达 . 它也容易受到 LS-L (直到我更改了 )

    此外,固定 useless use of cat .

    <files.txt  xargs stat -c %s | paste -sd+ - | bc
    
        11
  •  3
  •   MrMobileMan    9 年前

    如果没有安装BC,请尝试

    echo $(( $(... | paste -sd+ -) ))
    

    而不是

    ... | paste -sd+ - | bc
    

    $( ) <--返回执行命令的值

    $(( 1+2 )) <--返回评估结果

    echo <--将其反射到屏幕上

        12
  •  1
  •   0x6adb015    15 年前

    管道:

     cat files.txt | xargs ls -l | cut -c 23-30 | gawk 'BEGIN { sum = 0 } // { sum = sum + $0 } END { print sum }'
    
        13
  •  1
  •   Indeed is Trash    15 年前

    这是我的

    cat files.txt | xargs ls -l | cut -c 23-30 | sed -e :a -e '$!N;s/\n/+/;ta' | bc
    
        14
  •  1
  •   RichieHindle    14 年前
    #
    #       @(#) addup.sh 1.0 90/07/19
    #
    #       Copyright (C) <heh> SjB, 1990
    #       Adds up a column (default=last) of numbers in a file.
    #       95/05/16 updated to allow (999) negative style numbers.
    
    
    case $1 in
    
    -[0-9])
    
            COLUMN=`echo $1 | tr -d -`
    
            shift
    
    ;;
    
    *)
    
            COLUMN="NF"
    
    ;;
    
    esac
    
    echo "Adding up column .. $COLUMN .. of file(s) .. $*"
    
    nawk  ' OFMT="%.2f"                                       # 1 "%12.2f"
    
            { x = '$COLUMN'                                   # 2
    
              neg = index($x, "$")                            # 3
    
              if (neg > 0) X = gsub("\\$", "", $x)
    
              neg = index($x, ",")                            # 4
    
              if (neg > 1) X = gsub(",", "", $x)
    
              neg = index($x, "(")                            # 8 neg (123 & change
    
              if (neg > 0) X = gsub("\\(", "", $x)
    
              if (neg > 0) $x = (-1 * $x)                     # it to "-123.00"
    
              neg = index($x, "-")                            # 5
    
              if (neg > 1) $x = (-1 * $x)                     # 6
    
              t += $x                                         # 7
    
              print "x is <<<", $x+0, ">>> running balance:", t
    
            } ' $*
    
    
    # 1.  set numeric format to eliminate rounding errors
    # 1.1 had to reset numeric format from 12.2f to .2f 95/05/16
    #     when a computed number is assigned to a variable ( $x = (-1 * $x) )
    #     it causes $x to use the OFMT so -1.23 = "________-1.23" vs "-1.23"
    #     and that causes my #5 (negative check) to not work correctly because
    #     the index returns a number >1 and to the neg neg than becomes a positive
    #     this only occurs if the number happened to b a "(" neg number
    # 2.  find the field we want to add up (comes from the shell or defaults
    #     to the last field "NF") in the file
    # 3.  check for a dollar sign ($) in the number - if there get rid of it
    #     so we may add it correctly - $12 $1$2 $1$2$ $$1$$2$$ all = 12
    # 4.  check for a comma (,) in the number - if there get rid of it so we
    #     may add it correctly - 1,2 12, 1,,2 1,,2,, all = 12   (,12=0)
    # 5.  check for negative numbers
    # 6.  if x is a negative number in the form 999- "make" it a recognized
    #     number like -999 - if x is a negative number like -999 already
    #     the test fails (y is not >1) and this "true" negative is not made
    #     positive
    # 7.  accumulate the total
    # 8.  if x is a negative number in the form (999) "make it a recognized
    #     number like -999
    # * Note that a (-9) (neg neg number) returns a postive
    # * Mite not work rite with all forms of all numbers using $-,+. etc. *
    
        15
  •  1
  •   ceinmart    12 年前

    我喜欢用……

    echo "
    1
    2
    3 " | sed -e 's,$, + p,g' | dc 
    

    它们将显示每行的总和…

    适用于这种情况:

    ls -ld $(< file.txt) | awk '{print $5}' | sed -e 's,$, + p,g' | dc 
    

    合计是最后一个值…

        16
  •  0
  •   zsram    8 年前

    在我看来,最简单的解决方案是“expr”unix命令:

    s=0; 
    for i in `cat files.txt | xargs ls -l | cut -c 23-30`
    do
       s=`expr $s + $i`
    done
    echo $s
    
        17
  •  0
  •   John Kloian    8 年前

    纯巴什

    total=0; for i in $(cat files.txt | xargs ls -l | cut -c 23-30); do 
    total=$(( $total + $i )); done; echo $total
    
        18
  •  0
  •   Mario    7 年前
    sizes=( $(cat files.txt | xargs ls -l | cut -c 23-30) )
    total=$(( $(IFS="+"; echo "${sizes[*]}") ))
    

    或者你可以一边读尺寸一边求和。

    declare -i total=0
    while read x; total+=x; done < <( cat files.txt | xargs ls -l | cut -c 23-30 )
    

    如果你不在乎咬口大小和咬块大小,那么

    declare -i total=0
    while read s junk; total+=s; done < <( cat files.txt | xargs ls -s )
    
        19
  •  0
  •   ck reddy    6 年前
    cat files.txt | awk '{ total += $1} END {print total}'
    

    你可以用awk做同样的事情,它甚至跳过非整数。

    $ cat files.txt
    1
    2.3
    3.4
    ew
    1
    
    $ cat files.txt | awk '{ total += $1} END {print total}'
    7.7
    

    或者可以使用ls命令计算人类可读的输出

    $ ls -l | awk '{ sum += $5} END  {hum[1024^3]="Gb"; hum[1024^2]="Mb"; hum[1024]="Kb"; for (x=1024^3; x>=1024; x/=1024) { if (sum>=x) { printf "%.2f %s\n",sum/x,hum[x]; break; } } if (sum<1024) print "1kb"; }'
    15.69 Mb
    
    $ ls -l *.txt | awk '{ sum += $5} END  {hum[1024^3]="Gb"; hum[1024^2]="Mb"; hum[1024]="Kb"; for (x=1024^3; x>=1024; x/=1024) { if (sum>=x) { printf "%.2f %s\n",sum/x,hum[x]; break; } } if (sum<1024) print "1kb"; }'
    2.10 Mb