1

Please note that I'm aware of this and this but they didn't help me.

I want to combine the outputs of two commands.

ls -1sh

And

wc -l

so I can do something like:

<combined command> o.img 1.img
  1512 412K 0.png
  1269 320K 1.png
  2781 732K total

Also there is a small problem with that ls does not include the sum of sizes.

  • ls -1sh may also print directory items – RomanPerekhrest Jan 11 '18 at 8:51
  • How come!? Can you give me an example? – yukashima huksay Jan 11 '18 at 8:55
  • just run ls -1sh on the folder which contains subfolders, you'll see. In your case you can not get wc -l from subfolder – RomanPerekhrest Jan 11 '18 at 9:08
  • I thought you meant the items inside directories:)) – yukashima huksay Jan 11 '18 at 11:21
  • what useful information do you expect to get from running wc -l (which counts lines in a text file) on a .png image file? – cas Jan 11 '18 at 11:22
2

ls won't produce a total, but du can

du -sch *.csv
16K     LdevInfo.csv
8.0K    LunInfo.csv
4.0K    W.csv
4.0K    WwnInfo.csv
32K     total

wc will produce a total

 wc -l *.csv
  101 LdevInfo.csv
   66 LunInfo.csv
   62 W.csv
    8 WwnInfo.csv
  237 total

then simply join

join -j 2 -o 1.1,2.1,2.2 v w
101 16K LdevInfo.csv
66 8.0K LunInfo.csv
62 4.0K W.csv
8 4.0K WwnInfo.csv
237 32K total

where

  • -j 2 tell join to use field 2 for matching
  • -o 1.1,2.1,2.2 print specified fileld FILENUM.FIELDNUM

or, you can use additionnal awk to pretty format

join -j 2  v w| awk '{printf "%s\t%s\t%s\n",$2,$3,$1}'
101     16K     LdevInfo.csv
66      8.0K    LunInfo.csv
62      4.0K    W.csv
8       4.0K    WwnInfo.csv
237     32K     total

PS: I don't have any *.png I use *.csv but this should work.

  • Oh I'm so sorry! do you want me to send you some png!? – yukashima huksay Jan 11 '18 at 11:19
1

At first you have to fix the ls issue that it doesn't include the total with the following function:

myls() {
    if [ $# -gt 1 ] ; then
        ls -1sh "$@"
        ls -1s "$@" | cut -d' ' -f1 | awk '{s+=$1} END {print s}' | numfmt --to=iec --suffix=' total'
    else
        ls -1sh "$1"
    fi
}

You can put that in your .bashrc and load it.

After that you have to combine the outputs. There are multiple ways to do that. Here is one: First you combine all the outputs with paste. unfortunately paste only accepts files as arguments but you can use named pipes to take care of that:

combined() {
    paste <(wc -l "$@") <(myls "$@") | awk '{print $1, $3, $4}' | sort
}

You can put this function in your .bashrc now. I sorted them because I think that is mode readable. You can remove | sort if you don't want to sort them.

If you don't want to use an extra function you can do:

myd() {
    if [ $# -gt 1 ] ; then
        tmp=`ls -1sh "$@";ls -1s "$@" | cut -d' ' -f1 | awk '{s+=$1} END {print s}' | numfmt --to=iec --suffix=' total'`
    else
        tmp=`ls -1sh "$1"`
    fi
    paste <(wc -l "$@") <(echo "$tmp") | awk '{print $1, $3, $4}' | sort
}
  • This is working very well but it is giving me some other output to [1] 1009 [2] 1010 before the output and [1]- Done myls "$@" > fA [2]+ Done wc -l "$@" > fB after. – yukashima huksay Jan 11 '18 at 6:33
  • You don't need named pipe for that, you can just do paste <(myls "$0") <(wc -l "$0") as well. – Weijun Zhou Jan 11 '18 at 6:34
  • @WeijunZhou You are right. thanks. I'll edit my answer to include that. – tgwtdt Jan 11 '18 at 6:37
  • Also I don't want to use an extra command. how can I do that without myls? – yukashima huksay Jan 11 '18 at 6:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.