在grep之后在同一行打印awk输出



我有一个非常粗糙的脚本getinfo.sh,它从所有子文件夹中名为FILENAME1和FILENAME2的所有文件以及子文件夹的路径中获取信息。如果使用"getinfo.sh n">调用脚本,则awk结果应仅从FILENAME2中选取第n行。我想把所有的信息都打印在一行里!

问题是,如果我使用print而不是printf,信息会被写入新行,但我的脚本可以工作。如果我使用printf,我可以在脚本完成后看到命令propt中awk命令的最后一位,但它不是同一行中grep命令之后的paset。总的来说,整条线会很长,但这是故意的。你愿意告诉我我做错了什么吗?

#!/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')

如果这更容易的话,我也很乐意删除第n行?

解决方案:

#!/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')

您在注释中更清楚地说明了这一点。

我希望printf"%q"${PWD#*/}"和grep"Search_term"FILENAME1|tail-1和awk"{if(NR==n)printf"%s",$0}n=$1$2 FILENAME2的输出在一行中打印

因此,首先,我们有三个命令,每个命令打印一行输出。由于命令无关紧要,让我们将它们封装在函数中以简化答案:

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

要在没有换行符的情况下打印它们,我们可以:

  1. 使用命令替换,删除尾随的空换行符。带有一些打印f:

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

    或者一些回声:

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

    或附加到变量:

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

    等等

  2. 我们可以使用tr -d 'n':从流中删除换行符

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

    或者我们也可以只从第一个n-1命令中删除换行符,但我认为这不太可读:

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

如果我不传递数字,则应省略awk命令。

我看到您的awk命令同时扩展了$1$2,并且我看到只有$1作为n=$1环境变量传递给awk。我不知道$2是什么。你可以在$#的值上写if-s参数的数量:

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

对于您想要处理的每种情况都是类似的。记住正确的引用。

您的命令显示了未使用的参数$2,我删除了那个
您可以使用END块在awk的末尾添加一条换行符,但当您调用没有行号的脚本时,您也需要一条额外的换行符。echo即可。

#!/bin/bash
IFS=$'n'
while read -r fname ;
do
pushd $(dirname "${fname}") > /dev/null
# Add result of grep in same printf statement
printf '%s %s' "${PWD##*/}" "$(grep 'Search_term ' FILENAME1 | tail -1)"
if (( $# -eq 1 )); then
# use $1 as an awk variable, number n
# use $2 as a different file to read from
awk -v n=$1 '{ if(NR==n) printf "%s ",$0 }' FILENAME2
fi
# Add line-ending
echo
popd > /dev/null
done < <(find . -type f -name 'FILENAME1')

最新更新