我有一个非常粗糙的脚本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 ....; }
要在没有换行符的情况下打印它们,我们可以:
使用命令替换,删除尾随的空换行符。带有一些打印f:
printf "%s%s%sn" "$(cmd1)" "$(cmd2)" "$(cmd3)"
或者一些回声:
echo "$(cmd1) $(cmd2) $(cmd3)"
或附加到变量:
str="$(cmd1)" str+=" $(cmd2)" str+=" $(cmd3)" printf" %sn" "$str"
等等
我们可以使用
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')