在grep

时间:2019-01-30 10:54:15

标签: linux bash awk grep printf

我有一个非常粗糙的脚本getinfo.sh,它从所有子文件夹及其子路径中所有名为FILENAME1和FILENAME2的文件中获取信息。如果使用“ getinfo.sh n” 调用了脚本,则awk结果只能从FILENAME2中选择第n行。我希望所有信息都打印在一行中!

问题是,如果我使用print而不是printf,则信息将写入新行,但是我的脚本有效。如果我使用printf,脚本执行完后,我可以在命令属性中看到awk命令的最后一位,但是在同一行中的grep命令之后却没有设置。总的来说,完整的行很长,但这是有意的。您愿意告诉我我做错了什么吗?

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

如果这更容易,我也很乐意grep第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')

2 个答案:

答案 0 :(得分:1)

您在评论中更清楚了。

  

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

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

if($request->hasFile('images'))
{    
   $data = [];
   foreach($request->file('images') as $image)
   {
      $fileName = $image->getClientOriginalName();
      $destinationPath = public_path().'/images/' ;
      $file->move($destinationPath,$fileName);

      $data[] = '/images/'.$fileName;
   }
 $blogs->image =  json_encode($data);
}

要打印它们之间没有换行符,我们可以:

  1. 使用命令替换,此命令将删除结尾的空换行符。带有一些printf:

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

    或一些回声:

    printf "%s%s%s\n" "$(cmd1)" "$(cmd2)" "$(cmd3)"
    

    或附加到变量:

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

    以此类推。

  2. 我们可以使用str="$(cmd1)" str+=" $(cmd2)" str+=" $(cmd3)" printf" %s\n" "$str" 从流中删除换行符:

    tr -d '\n'

    或者我们也可以仅从前{ cmd1 cmd2 cmd3 } | tr -d '\n' echo # newlines were removed, so add one to the end. 个命令中删除换行符,但是我认为这不太可读:

    n-1
  

如果我不输入数字,则应省略awk命令。

我看到您的{ cmd1 cmd2 } | tr -d'\n' cmd3 # the trailing newline will be added by cmd3 命令同时扩展了awk$1,并且我只看到$2作为$1环境变量传递给{ {1}}。我不知道什么是n=$1。您可以在参数个数awk的值上写if-s:

$2

,并针对您要处理的每种情况进行类似处理。记住正确的报价。

答案 1 :(得分:1)

您的命令显示未使用的参数$2,我删除了该参数。
您可以使用awk块在END的末尾添加换行符,但是在调用没有行号的脚本时还需要一个额外的换行符。 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')