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:
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.
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.