4d4c
4d4c

Reputation: 8159

Combine output of two command in unix system

I need to combine output of two commands.

For example:

If I input ls -l && file * it will give me

-rw-rw-r-- 1 user user 1356 2012-01-21 07:45 string.c
-rwxrwxr-x 1 user user 7298 2012-01-21 07:32 string_out
-rw-rw-r-- 1 user user  777 2012-01-18 21:44 test

string.c:   ASCII C program text, with CRLF line terminators
string_out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
test:       POSIX shell script text executable

but what I want is:

-rw-rw-r-- 1 user user 1356 2012-01-21 07:45 string.c string.c:   ASCII C program text, with CRLF line terminators
-rwxrwxr-x 1 user user 7298 2012-01-21 07:32 string_out string_out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
-rw-rw-r-- 1 user user  777 2012-01-18 21:44 test test:       POSIX shell script text executable

Any suggestions how to do this?

Upvotes: 12

Views: 12693

Answers (5)

Kyle Burton
Kyle Burton

Reputation: 27528

Shiplu has a nice simple solution, in bash you can do it without using variables:

for x in *; do 
  echo "$(ls -dl $x) $(file $x)"
done;

Or:

for x in *; do echo "$(ls -dl $x) $(file $x)"; done;

In bash, $(cmd) takes the output of cmd and places it onto the command line, which is very useful for situations like this.

The $() form can be less error prone than using backticks (`cmd`) because it nests safely:

echo $(ls -l $(which bash))

With backticks you have to multiply escape things like quotes

Upvotes: 7

glenn jackman
glenn jackman

Reputation: 246774

paste is your friend here. Using bash process substitution:

paste <(ls -l | sed 1d) <(file *)

edit: added sed command to delete first line of ls output ("total: xx")

Upvotes: 5

jaypal singh
jaypal singh

Reputation: 77085

Using awk:

awk '
NR==FNR{a[$9":"]=$0;next} 
($1 in a){printf("%-60s\t%-s\n",a[$1],$0)}' <(ls -l) <(file *)

Using while loop (Similar to @Shiplu and @Kyle's answer but using while loop with field descriptors:

while read list && read type <&3; do 
   echo "$list $type"; 
done < <(tail +2 <(ls -l)) 3< <(file *)

Upvotes: 1

Shiplu Mokaddim
Shiplu Mokaddim

Reputation: 57650

You need a loop

 for x in *; 
 do 
      ls=`ls -dl $x`
      c=`file $x`
      echo "$ls $c"
 done;

In my Cygwin there is no file command. So I did it with wc. Their output format is almost same.

$ for x in *; do ls=`ls -l $x`; c=`wc -c $x`; echo "$ls : $c"; done;
-rwxr-xr-x 1 shiplu None 18460 Dec 23 16:27 a.exe : 18460 a.exe
-rw-r--r-- 1 shiplu None 340 Dec 23 16:27 tok.c : 340 tok.c

Upvotes: 1

Greg Hewgill
Greg Hewgill

Reputation: 992937

You can use the join command for this, but it might be tricky to do it all in one command line. If you create two files with the output of each command, it's pretty straightforward. You may need to massage the output a bit (such as removing the trailing : in the output of file).

Upvotes: 1

Related Questions