Is there any way in Linux to show the output of a command being used multiple times side by side?

Viewed 128

I am a noob in Linux and Shell Scripting and I was trying to write a shell script that would display a directory listing based on the command line argument being passed. It would accept the 4 positional arguments namely F, D, T and P and display accordingly.

Sample Input and Output:

$ ./list.sh F D T P 
File name       date        time        permission 
-------------   ------      -----       --------------- 
Filename1       date        time        permission 
Filename2       date        time        permission 

Total no. of files : <total number> 
Total no of normal file : <number> 
Total no of directory : <number>

The arguments could be shuffled. I tried to write a shell script which is able to do the work but not able to display as I want.

#!/bin/bash

args=("$@") # Storing all the positional args into an array
n=0
x=0

while [ $n -ne 4 ]
do
    case "${args[$n]}" in 
        F)  argsVal[$x]=9 ;;
        D)  argsVal[$x]=6 ;;
        T)  argsVal[$x]=8 ;;
        P)  argsVal[$x]=1 ;;
        *)  echo "Invalid Option" ;;
    esac
    n=`expr $n + 1`
    x=`expr $x + 1`
done

n=0
while [ $n -ne 4 ]
do 
    case "${argsVal[$n]}" in
        
    1) echo -e "Permissions(P)\t\c" ;;

    6) echo -e "Date(D)\t\c" ;;

    8) echo -e "Time(T)\t\c" ;;

    9) echo -e "FileNames(F)\t\c" ;;
    
    *) ;;
    esac
    n=`expr $n + 1`
done

echo -e "\n"

n=0
while [ $n -ne 4 ]
do 
    case "${argsVal[$n]}" in
    
    1) 
    awk '{print $1}' listout ;;

    6) 
    awk '{print $6,$7}' listout ;;

    8)
    awk '{print $8}' listout ;;

    9)
    awk '{print $9}' listout ;;
    
    *) ;;
    esac
    n=`expr $n + 1`
done

The output is :

Permissions(P)  Date(D) Time(T) FileNames(F)

-rw-r--r--
-rwxr--r--
-rwxr--r--
-rwxr--r--
-rwxr--r--
Jun 18
Jun 19
Jun 6
Jun 18
Jun 6
22:04
12:04
20:45
22:32
21:17
listout
list.sh
script.sh
test1.sh
validvoter.sh
3 Answers

Change the last while loop code

n=0
while [ $n -ne 4 ]
do 
    case "${argsVal[$n]}" in
    
    1) 
    awk '{print $1}' listout ;;

    6) 
    awk '{print $6,$7}' listout ;;

    8)
    awk '{print $8}' listout ;;

    9)
    awk '{print $9}' listout ;;
    
    *) ;;
    esac
    n=`expr $n + 1`
done

to

awk -v a="${argsVal[0]}" -v b="${argsVal[1]}" -v c="${argsVal[2]}" -v d="${argsVal[3]}" '{printf("%s\t%s\t%s\t%s\n", $a,$b,$c,$d)}' listout

One awk command will scan the hole file, and it can print the columns what you want.

Reference man awk we get some usage like that:

-v var=val
--assign var=val
Assign the value val to the variable var, before execution of the program begins.  Such variable values are available to the BEGIN rule of an AWK program.
 
printf fmt, expr-list Format and print.  See The printf Statement, below.

Use column to format columns:

stat -c "%n %y %A" * | column -t

Try with printf command:

#!/bin/bash

while [ $# -gt 0 ] ; do
  case $1 in

    F) 
      arg="$arg\$9, " 
      tit=("${tit[@]}" "File name (F)")
      unl=("${unl[@]}" "-------------")
      fmt="$fmt%-35s"
      ;;
    P) 
      arg="$arg\$1, " 
      tit=("${tit[@]}" "Permissions (P)")
      unl=("${unl[@]}" "---------------")
      fmt="$fmt%-17s"
      ;;
    T) 
      arg="$arg\$8, "
      tit=("${tit[@]}" "Time (T)")
      unl=("${unl[@]}" "--------")
      fmt="$fmt%-10s"
      ;;
    D) 
      arg="$arg\$6\" \"\$7, "
      tit=("${tit[@]}" "Date (D)")
      unl=("${unl[@]}" "--------")
      fmt="$fmt%-10s"
      ;;
    *)
      echo "invalid option $1"
      exit 1
  esac
  shift
done

if [ -z "$arg" ] ; then
  echo "missing options"
  exit 2
fi

arg=${arg%, } # remove trailing comma and space from $arg

printf "$fmt\\n" "${tit[@]}"
printf "$fmt\\n" "${unl[@]}"

ls -l | grep -v '^total' > listout

grep -v "^total" listout | 
  awk "{ printf \"$fmt\\n\", $arg}"

tf=$(cat listout | wc -l)
tnf=$(grep '^-' listout | wc -l)
td=$(grep '^d' listout | wc -l)

echo
echo "Total number of files:           $tf"
echo "Total number of normal files:    $tnf"
echo "Total number of directories:     $td"
Related