Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have files like this

$ cat trapetz
x = 0:0.0001:7pi
plot(x, sin(x).*cos(x))
Area = trapz(x, sin(x).*cos(x))
$ cat simpson 
f = inline(sin(x).*cos(x));
Area2 = quad(f, 0, 7pi, 1e-16)

I want something like this

$ cat -b -t MISSING? trapetz simpson 
     traapetz 
     1  x = 0:0.0001:7pi
     2  plot(x, sin(x).*cos(x))
     3  Area = trapz(x, sin(x).*cos(x))
     simpson
     1  f = inline(sin(x).*cos(x));
     2  Area2 = quad(f, 0, 7pi, 1e-16)

or even better if some easy way to add wc there:

$ find |tee |...|wc... I feel now reinventing the wheel, there must be some ready...
     traapetz: xyz chars
     1  x = 0:0.0001:7pi
     2  plot(x, sin(x).*cos(x))
     3  Area = trapz(x, sin(x).*cos(x))
     simpson: zyx chars
     1  f = inline(sin(x).*cos(x));
     2  Area2 = quad(f, 0, 7pi, 1e-16)

but I get

$ cat -b -t trapetz simpson 
     1  x = 0:0.0001:7pi
     2  plot(x, sin(x).*cos(x))
     3  Area = trapz(x, sin(x).*cos(x))
     4  f = inline(sin(x).*cos(x));
     5  Area2 = quad(f, 0, 7pi, 1e-16)

Not really cat needed but some easy tool to share and show code snippets like the above, not pastebin. I want some standard command line thing. I am trying to create easy puzzle -pasting for codegolf.se so people could reproduce things easily...

share|improve this question
    
see also cat files with directory –  Gilles Aug 28 '12 at 23:48
add comment

4 Answers

up vote 3 down vote accepted

A very rough awk implementation:

BEGIN{
    OLDFILENAME="";
}
FNR==1{
    if (OLDFILENAME != "") {
        printf("#### Processed (chars: %s - lines: %s)\n", FWC, FLC);
    }
    printf("#### Processing: %s\n", FILENAME);
    OLDFILENAME=FILENAME;
    FWC=0;
    FLC=0;
}
{
    printf("%04d - %s\n", FNR, $0);
    FWC = FWC + length($0);
    FLC = FLC + 1;
}
END{
    if (OLDFILENAME != "") {
        printf("#### Processed (chars: %s - lines: %s)\n", FWC, FLC);
    }
}

Execute awk -f AWKFILE trapetz simpson to get:

#### Processing: trapetz
0001 - x = 0:0.0001:7pi
0002 - plot(x, sin(x).*cos(x))
0003 - Area = trapz(x, sin(x).*cos(x))
#### Processed (chars: 70 - lines: 3)
#### Processing: simpson
0001 - f = inline(sin(x).*cos(x));
0002 - Area2 = quad(f, 0, 7pi, 1e-16)
#### Processed (chars: 57 - lines: 2)
share|improve this answer
add comment

Quick shell script:

#!/bin/sh
# usage: scriptname file1 file2 ...

for file in "$@"
do
    [ -f "$file" ] || continue
    set -- `wc "$file"`
    echo "${file}: lines $1 words $2 bytes $3"
    cat -b -t "$file"
done

It behaves like your sample output, so missing files are silently ignored.

share|improve this answer
add comment

tail -n +1 trapetz simpson will print each file with a leading header giving the file name. nl trapetz simpson prints line numbers but no file names. You'll need to use either awk or some shell glue to combine the two.

for x in trapetz simpson; do
  echo "$x: $(wc -c <"$x") bytes"
  nl "$x"
done

Here's an awk solution which prints the byte count at the bottom:

awk '
    FNR == 1 && NR != 1 {print "end", fn, chars, "characters"; bytes=0}
    END {print "end", fn, chars, "characters"}
    FNR == 1 {print "begin", FILENAME; fn=FILENAME}
    1 {chars += 1 + length; printf "%7d ", FNR; print}
' trapetz simpson
share|improve this answer
    
Line FNR == 1 && NR != 1... prints the wrong filename... and it counts characters, not bytes (re non ASCII text) –  Peter.O Oct 29 '11 at 16:48
add comment

Here is sed + wc + nl + cat (and a bash loop)

set trapetz simpson
for file in "$@" ;do
  { wc -l -m "$file"; cat "$file"; } | 
    sed -nr '1{N;s/(.*)\n(.*)/\2\x01\1/};p' | nl |
    sed -r '1{s/(.*)\x01 *([0-9]+) +([0-9]+) (.*)$/\4  (\2 lines, \3 chars)\n\1/};$s/.*/&\n/' 
done; echo "(${#@} files)"

Output

trapetz  (3 lines, 73 chars)
     1  x = 0:0.0001:7pi
     2  plot(x, sin(x).*cos(x))
     3  Area = trapz(x, sin(x).*cos(x))

simpson  (2 lines, 59 chars)
     1  f = inline(sin(x).*cos(x));
     2  Area2 = quad(f, 0, 7pi, 1e-16)
  
(2 files)

Here is sed + grep (no wc though).

Using sed for situations such as this is good for regex and sed juggling practice, but when the juggling gets to be too much, the ability to use a single tool (eg. awk) is ususlly the better option..

grep -nH '.' trapetz simpson | sed -nre 'G; s/^([^:]+):.*\n\1/&/; tp; h; s/^([^:]+).*/\1/p; g; :p; s/^[^:]+:([^:]+):(.*)\n.*/0000\1  \2/; s/^[^ ]*([^ ]{4})(.*)/\1\2/p; g; s/^([^:]+).*/\1/; h'

Or a more readable representation :)

grep -nH '.' trapetz simpson |
  sed -nre '
  G                      # pattern+=nl+hold
  s/^([^:]+):.*\n\1/&/   # if
      t printline        # when prev==curr branch to printline   
  : new_file             # when prev!=curr print header
      h                  # hold the pattern  
      s/^([^:]+).*/\1/p  # print header (filename)
      g                  # get the held pattern 
  : printline            # print current line (with line number) 
      s/^[^:]+:([^:]+):(.*)\n.*/0000\1  \2/   # zero pad number  
      s/^[^ ]*([^ ]{4})(.*)/\1\2/p            # number width = 4
      g                  # get the held pattern 
      s/^([^:]+).*/\1/   # extract filename
      h                  # hold the filename
'   

Output

trapetz
0001  x = 0:0.0001:7pi
0002  plot(x, sin(x).*cos(x))
0003  Area = trapz(x, sin(x).*cos(x))
simpson
0001  f = inline(sin(x).*cos(x));
0002  Area2 = quad(f, 0, 7pi, 1e-16)
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.