Skip to content
Advertisement

Printing awk output in same line after grep

I have a very crude script getinfo.sh that gets me information from all files with name FILENAME1 and FILENAME2 in all subfolders and the path of the subfolder. The awk result should only pick the nth line from FILENAME2 if the script is called with “getinfo.sh n”. I want all the info printed in one line!

The problem is that if i use print instead of printf the info is written to a new line but my script works. If i use printf i can see the last bit of the awk command in the command propt after the script ist done, but it is not paset after the grep command in the same line. All in all the complete line would be pretty long, but that is intentionally. Would you be willing to tell me what i am doing wrong?

#!/bin/bash

IFS=$'n'
while read -r fname ;
do
    pushd $(dirname "${fname}") > /dev/null
    printf '%q' "${PWD##*/}"
    grep 'Search_term ' FILENAME1 | tail -1
    awk '{ if(NR==n) printf "%s",$0 }' n=$1 $2 FILENAME2
    popd > /dev/null
done < <(find . -type f -name 'FILENAME1')

I would also be happy to grep the nth line if this is easier?

SOLUTION:

#!/bin/bash

IFS=$'n'
while read -r fname ;
do
    pushd $(dirname "${fname}") > /dev/null
   {
     printf '%q' "${PWD##*/}"
     grep 'Search_term' FILENAME1 | tail -1
   } | tr -d 'n'

   if [ "$1" -eq "$1" ] 2>/dev/null
   then
        awk '{ if(NR==n) printf "%s",$0 }' n="$1" FILENAME2
   fi

    printf "n"
    popd > /dev/null
done < <(find . -type f -name 'FILENAME1')

Advertisement

Answer

You made it clearer in the comments.

I want the output of printf ‘%q’ “${PWD##*/}” and grep ‘Search_term ‘ FILENAME1 | tail -1 and awk ‘{ if(NR==n) printf “%s”,$0 }’ n=$1 $2 FILENAME2 to be printed in one line

So first, we have three commands, that each print a single line of output. As the commands do not matter, let’s wrap them in functions to simplify the answer:

cmd1() { printf '%qn' "${PWD##*/}"; }
cmd2() { grep .... ; }
cmd3() { awk ....; }

To print them without newlines between them, we can:

  1. Use a command substitution, which removes trailing empty newlines. With some printf:

    printf "%s%s%sn" "$(cmd1)" "$(cmd2)" "$(cmd3)"
    

    or some echo:

    echo "$(cmd1) $(cmd2) $(cmd3)"
    

    or append to a variable:

    str="$(cmd1)"
    str+=" $(cmd2)"
    str+=" $(cmd3)"
    printf" %sn" "$str"
    

    and so on.

  2. We can remove newlines from the stream, using tr -d 'n':

    {
         cmd1
         cmd2
         cmd3
    } | tr -d 'n'
    echo # newlines were removed, so add one to the end.
    

    or we can also remove the newlines only from the first n-1 commands, but I think this is less readable:

    {
       cmd1
       cmd2
    } | tr -d'n'
    cmd3 # the trailing newline will be added by cmd3
    

If i do not pass a number the awk command should be omited.

I see that your awk command expands both $1 and $2, and i see only $1 to be passed as the n=$1 environment variable to awk. I don’t know what is $2. You can write if-s on the value of $# the number of arguments:

if (($# == 2)); then
    awk '{ if(NR==n) printf "%s",$0 }' n="$1" "$2" FILENAME2
fi

and similar for each case you want to handle. Remember about proper quoting.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement