ইউনিক্স শেল এ সংখ্যার কলাম যুক্ত করুন


198

ফাইলগুলির একটি তালিকা দেওয়া files.txt, আমি এই জাতীয় আকারগুলির একটি তালিকা পেতে পারি:

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

যা এরকম কিছু তৈরি করে:

  151552
  319488
 1536000
  225280

আমি কিভাবে পেতে পারেন মোট সমস্ত সংখ্যার?

উত্তর:


383
... | paste -sd+ - | bc

আমি খুঁজে পাওয়া সংক্ষিপ্ততমটি ( ইউনিক্স কমান্ড লাইন ব্লগ থেকে)।

সম্পাদনা করুন:- বহনযোগ্যতার জন্য যুক্তি যুক্ত করেছেন , ধন্যবাদ @ ডগবার্ট এবং @ ওউইন।


খুশী হলাম। সোলারিসেও শেষের দরকার
ওভেন বি

8
alias sum="paste -sd+ - | bc"শেল সমাপ্তিতে যোগ হয়েছে, ধন্যবাদ সাথী
এসএফএফ

. . .| x=$(echo <(cat)); echo $((0+${x// /+}+0))আপনি যদি
সারাক্ষণ

13
@ এসএলএফ, নজর রাখুন, আপনি মাত্র ওভারলোড করেছেন/usr/bin/sum
কিউনিল

3
সাবধান, bcকিছু সিস্টেমে পাওয়া যায় না! awkঅন্যদিকে, পসিক্স সম্মতির জন্য প্রয়োজনীয় (আমি বিশ্বাস করি)।
ভিকেটেক

154

এখানে যায়

cat files.txt | xargs ls -l | cut -c 23-30 | 
  awk '{total = total + $1}END{print total}'

34
Awk ব্যবহার করা একটি সূক্ষ্ম ধারণা, তবে কেন রাখবেন cut? এটি একটি পূর্বাভাসযোগ্য কলাম নম্বর, তাই ব্যবহার করুন... | xargs ls -l | awk '{total = total + $5}{END{print total}'
ডেমকে --- --- প্রাক্তন মডারেটর বিড়ালছানা

3
আপনি অবশ্যই সঠিক - ইতিমধ্যে যা ছিল তার শেষে কেবল যুক্ত করা সহজ ছিল :-)
গ্রেগ রেইনল্ডস

2
@ ডিএমকেকের জবাবের মধ্যে একটি বন্ধনী খুব বেশি :)
ডঃ জানু-ফিলিপ গেহর্কেকে

7
এটিকে কিছুটা ছোট করার জন্য, আপনি total+=$1পরিবর্তে ব্যবহার করতে পারেনtotal = total + $1
ভিকেটেক

10

Ls -l এর আউটপুট থেকে ফাইলের আকার পেতে কাটা ব্যবহার না করে আপনি সরাসরি ব্যবহার করতে পারেন:

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

আওক "$ 5" পঞ্চম কলাম হিসাবে ব্যাখ্যা করে। এটি ls -l এর কলাম যা আপনাকে ফাইলের আকার দেয়।


10

ফাইলনেমে ফাঁকা স্থান থাকলে বিড়াল কাজ করবে না। পরিবর্তে এখানে পার্ল ওয়ান-লাইনার।

perl -nle 'chomp; $x+=(stat($_))[7]; END{print $x}' files.txt

8
python3 -c"import os; print(sum(os.path.getsize(f) for f in open('files.txt').read().split()))"

অথবা আপনি যদি কেবল সংখ্যার যোগ করতে চান তবে পাইপটি এখানে করুন:

python3 -c"import sys; print(sum(int(x) for x in sys.stdin))"

1
... | python -c'import sys; print(sum(int(x) for x in sys.stdin))'যখন পাইথন 2 এই বছরের শেষে অদৃশ্য হয়ে যায়।
eponymous

ডন @ ঝিনুক: ~ / ডকুমেন্টস $ বিড়াল কর | পাইথন 3-সি "এসিসি আমদানি করুন; মুদ্রণ করুন (সিএসএসটিডিনে এক্স এর জন্য সমষ্টি (এক্স) > ", লাইন 1, <জেনেক্সপ্রে> মান মূল্য: 10 এর ভিত্তিতে () এর জন্য অবৈধ আক্ষরিক: '\ n'
উজ্জ্বল নয়

5

TMTWWTDI : পার্লের একটি ফাইল আকার অপারেটর রয়েছে (-র)

perl -lne '$t+=-s;END{print $t}' files.txt

5

আপনার স্ট্যাটাস থাকলে পুরো এলএস-এল এবং তারপরে কাটা বরং গুলিয়ে যায় । এটি ls -l এর সঠিক বিন্যাসেও ঝুঁকিপূর্ণ (আমি কাটার জন্য কলাম নম্বরগুলি পরিবর্তন না করা পর্যন্ত এটি কাজ করে না )

এছাড়াও, বিড়ালের অকেজো ব্যবহার স্থির করুন ।

<files.txt  xargs stat -c %s | paste -sd+ - | bc

2
হাহ। ইউনিক্স 32 বছর ধরে ব্যবহার করা হয়েছে, এবং কখনই জানত না যে <infile commandএটি একই (এবং এর চেয়ে ভাল ক্রমে) command <infile
ক্যামিল গৌডেসুন

5

আপনার কাছে বিসি ইনস্টল না থাকলে চেষ্টা করুন

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

পরিবর্তে

... | paste -sd+ - | bc

$( ) <- কমান্ড কার্যকর করার মানটি ফিরিয়ে দিন

$(( 1+2 )) <- মূল্যায়ন ফলাফল ফিরে

echo <- এটি স্ক্রিনে প্রতিধ্বনিত করুন


4

আপনি যদি কেবল অজস্র বা অন্য অনুবাদক ছাড়াই শেল স্ক্রিপ্টিং ব্যবহার করতে চান তবে আপনি নিম্নলিখিত স্ক্রিপ্টটি ব্যবহার করতে পারেন:

#!/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

3

আমি পরিবর্তে "ডু" ব্যবহার করব।

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

আপনি যদি কেবল সংখ্যাটি চান:

cat files.txt | xargs du -c | tail -1 | awk '{print $1}'

5
ডিস্ক ব্যবহার! ফাইলের আকার du ডিস্ক ব্যবহারের রিপোর্ট করে।
0x6adb015

4
আমি মনে করি -বি সুইচ আমার যা প্রয়োজন তা করতে পারে।
রিচিহিন্ডল

@ 0x6adb015 ভাল জ্ঞান। ধন্যবাদ আমি বুঝতে পারি নি।
মাইকেল জোনস

3
ওপিতে সংখ্যার কলাম যুক্ত হওয়ার সুনির্দিষ্ট কারণের জন্য এটি একটি কার্যকর উত্তর, তবে সাধারণ সংখ্যা সংযোজনের ক্ষেত্রে এটি সংক্ষিপ্ত হয়। (আমি নিজেই সমস্ত সময় "ডু" ব্যবহার করি তবে কমান্ড-লাইন গণিতের সন্ধানে আমি এখানে এসেছি: :-))
মাইকেল এইচ।

12
এটি files.txtবড় হলে কাজ করবে না । যদি পাইপযুক্ত আর্গুমেন্টগুলির সংখ্যা xargsনির্দিষ্ট প্রান্তিকের কাছে পৌঁছায়, এটি তাদের একাধিক কলের মাধ্যমে ভেঙে দেয় du। শেষে প্রদর্শিত মোটটি duপুরো তালিকা নয়, কেবলমাত্র শেষ কলের জন্য মোট ।
ম্যাথু সিমোনউ


1

গাaw় পাইপ:

 cat files.txt | xargs ls -l | cut -c 23-30 | gawk 'BEGIN { sum = 0 } // { sum = sum + $0 } END { print sum }'


1
#
#       @(#) 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. *

1

আমি ব্যবহার করতে চাই ...

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

তারা প্রতিটি লাইনের যোগফল প্রদর্শন করবে ...

এই পরিস্থিতির উপর প্রয়োগ:

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

মোটটি সর্বশেষ মান ...


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

আপনি কাজটি করতে একইভাবে এটি ব্যবহার করতে পারেন এটি এমনকি অ ইন্টিজারগুলিও এড়িয়ে যায়

$ 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

আপনার awk '{ total += $1} END {print total}' files.txt
পাইপও

0

আমার মতে, এর সহজ সমাধান হ'ল "এক্সপ্রেস" ইউনিক্স কমান্ড:

s=0; 
for i in `cat files.txt | xargs ls -l | cut -c 23-30`
do
   s=`expr $s + $i`
done
echo $s


0
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 )

0

আপনার যদি আর থাকে তবে আপনি এটি ব্যবহার করতে পারেন:

> ... | Rscript -e 'print(sum(scan("stdin")));'
Read 4 items
[1] 2232320

যেহেতু আমি আর এর সাথে স্বাচ্ছন্দ্য বোধ করছি, আমার কাছে আসলে এই জাতীয় জিনিসের জন্য বেশ কয়েকটি উপাত্ত রয়েছে যাতে আমি bashএই বাক্য গঠনটি মনে না রেখেই এগুলিকে ব্যবহার করতে পারি । এই ক্ষেত্রে:

alias Rsum=$'Rscript -e \'print(sum(scan("stdin")));\''

যা আমাকে করুক

> ... | Rsum
Read 4 items
[1] 2232320

অনুপ্রেরণা: একক কমান্ডে ন্যূনতম, সর্বোচ্চ, মধ্যম এবং গড় সংখ্যাগুলির তালিকা পাওয়ার কোনও উপায় কি?

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.