【问题标题】:issue for condition on unique raws in bashbash 中唯一行的条件问题
【发布时间】:2021-03-21 23:43:11
【问题描述】:

我想在文件中打印表格的行,问题是当我使用readline 时,我多次重印结果,这是我的输入文件

aa      ,DEC    ,file1.txt
aa      ,CHAR   ,file1.txt    
cc      ,CHAR   ,file1.txt  
dd      ,DEC    ,file2.txt
bb      ,DEC    ,file3.txt
bb      ,CHAR   ,file3.txt 
cc      ,DEC    ,file1.txt

这是我想要的结果:

打印在file1.txt中

aa#DEC,CHAR
cc#CHAR,DEC

在file2.txt中打印

dd#DEC

打印在file3.txt中

bb#DEC,CHAR

这是我的尝试:

(cat input.txt|while read line
do
table=`echo $line|cut -d"," -f1
variable=`echo $line|cut -d"," -f2
file=`echo $line|cut -d"," -f3

echo ${table}#${variable}, 

done ) > ${file}

【问题讨论】:

标签: bash awk sh


【解决方案1】:

这可以通过gnu awk 一次性完成,如下所示:

awk -F ' *, *' '{
   map[$3][$1] = (map[$3][$1] == "" ? "" : map[$3][$1] ",") $2
}
END {
   for (f in map)
      for (d in map[f])
         print d "#" map[f][d] > f
}' file

这将填充此数据:

=== file1.txt ===

aa#DEC,CHAR
cc#CHAR,DEC

=== file2.txt ===

dd#DEC

=== file3.txt ===

bb#DEC,CHAR

【讨论】:

    【解决方案2】:

    对于您展示的示例,您能否尝试在 GNU awk 中的展示示例中进行跟踪、编写和测试。

    awk '
    {
      sub(/^,/,"",$3)
    }
    FNR==NR{
      sub(/^,/,"",$2)
      arr[$1,$3]=(arr[$1,$3]?arr[$1,$3]",":"")$2
      next
    }
    (($1,$3) in arr){
      close(outputFile)
      outputFile=$3
      print $1"#"arr[$1,$3] >> (outputFile)
      delete arr[$1,$3]
    }
    '  Input_file  Input_file
    

    说明:为上述添加详细说明。

    awk '                         ##Starting awk program from here.
    {
      sub(/^,/,"",$3)             ##Substituting starting comma in 3rd field with NULL.
    }
    FNR==NR{                      ##Checking condition FNR==NR will be true when first time Input_file is being read.
      sub(/^,/,"",$2)             ##Substituting starting comma with NULL in 2nd field.
      arr[$1,$3]=(arr[$1,$3]?arr[$1,$3]",":"")$2 
    ##Creating arr with index of 1st and 3rd fields, which has 2nd field as value.
      next                        ##next will skip all further statements from here.
    }
    (($1,$3) in arr){             ##Checking condition if 1st and 3rd fields are in arr then do following.
      close(outputFile)           ##Closing output file, to avoid "too many opened files" error.
      outputFile=$3               ##Setting outputFile with value of 3rd field.
      print $1"#"arr[$1,$3] >> (outputFile)
    ##printing 1st field # arr value and output it to outputFile here.
      delete arr[$1,$3]           ##Deleting array element with index of 1st and 3rd field here.
    }
    ' Input_file Input_file       ##Mentioning Input_file 2 times here.
    

    【讨论】:

    • 它确实有效,但你能在你的代码中对第 7 行给出更多解释吗? “?”是什么意思和 ,",":"")$2 在第 14 行和第 14 行,谢谢
    • @BADS,欢迎您,很高兴它对您有所帮助。它使用三元运算符。它的语法类似于:condition_check?value(when condition is TRUE):value(when condition is false) 格式。 arr[$1,$3] 表示检查其是否为 NOT NULL,然后将当前行的第二个字段值附加到其现有值(根据要求)或将其新添加到数组中,因为数组将为空。我希望它现在清楚了,干杯。
    【解决方案3】:

    您的代码中有几个错误。您可以使用内置的read 以逗号分隔,括号完全没有必要。

    while IFS=, read -r table variable file
    do
        echo "${table}#${variable}," >>"$file"
    done< input.txt
    

    done 之后的重定向中使用$file 是错误的; shell 想要在定义file 之前打开要重定向到的文件句柄。但是根据您的要求,每一行都应该转到不同的`文件。

    还要注意quoting fixesuseless cat. 的省略

    使用 Awk 后处理器将具有相同值的字段包装到同一行会很容易,但是您也可以在 Awk 中完成所有这些操作,就像您已经收到的其他答案一样。

    【讨论】:

      猜你喜欢
      • 2011-05-03
      • 2013-04-05
      • 1970-01-01
      • 2020-03-11
      • 2021-10-08
      • 2018-05-24
      • 2017-06-10
      • 2014-07-07
      • 1970-01-01
      相关资源
      最近更新 更多