【问题标题】:Append Data to a specific line number using SED/AWK in Unix在 Unix 中使用 SED/AWK 将数据附加到特定的行号
【发布时间】:2015-12-04 05:35:38
【问题描述】:

我有一个用冒号分隔的文件,看起来像这样..

StudentID:LastName:FirstName: 0962344:Bob:Billy: 0123456:Joe:Black: 0987654:Jess:Foo:

第一行将始终包含标题。假设所有行中第三个之后的每个字段都包含成绩。

假设我将 hw1 添加到 only Joe Black,因为他很早就完成了。

StudentID:LastName:FirstName:hw1: 0962344:Bob:Billy:: 0123456:Joe:Black:100: 0987654:Jess:Foo::

第一个问题)

当我将行号添加到某些行时,我将如何追加到行尾,或者追加到所有行但具有不同的数据(冒号、成绩或上述作业)?

第二个问题)

我如何将数据添加到其他学生的新创建字段中。如果文件中有更多成绩,请为 Bob 和 Jess 添加 hw1 的成绩。比如……

StudentID:LastName:FirstName:hw1:hw2: 0962344:Bob:Billy:HOW DO I ADD HERE:50: 0123456:Joe:Black:100:50: 0987654:Jess:Foo:AND HERE:50:

我假设我只能使用 Awk,因为 sed 会遍历每一行。

【问题讨论】:

  • 在您的示例数据中,标题按 LastName FirstName 排序,实际记录是 FirstName LastName。我将在标题中切换名字和姓氏。

标签: regex bash unix awk sed


【解决方案1】:

呆呆

问题1:

 awk -F':' -vOFS=':' '{NF+=1}NR==1{$(NF-1)="hw1"}/Joe/{$(NF-1)=100}1' file
StudentID:LastName:FirstName:hw1:
 0962344:Bob:Billy::
 0123456:Joe:Black:100:
 0987654:Jess:Foo::

问题2:

awk -F':' -vOFS=':' 'NR==1{for(i=0;++i<=NF;)if($i=="hw1")l=i}/Bob/{$l="Your Num"}/Jess/{$l="Your New Num"}1' file
StudentID:LastName:FirstName:hw1:hw2:
 0962344:Bob:Billy:Your Num:50:
 0123456:Joe:Black:100:50:
 0987654:Jess:Foo:Your New Num:50:

【讨论】:

  • 如果我在哪里输入每个学生的成绩,而不仅仅是乔,我将如何完成这项工作。这行得通吗? awk -F':' -vOFS=':' '{NF+=1}NR==1{$(NF-1)="$title"}/$fName/{$(NF-1)=$grade}1' file
  • awk -F':' -vOFS=':' -vg=$grade -vt=$title -vn="$f" '{NF+=1}NR==1{$(NF-1)=t}$2==n{$(NF-1)=g}1' file
  • 那只会打印出标题hw01,-vn="$f",你的意思是-vn=$fName
  • -vn="$f" 是姓名,例如“Joe”。
【解决方案2】:

不用 awk 也能做到。当数据存储在文件输入中时,您可以使用while read -r fields; do .. done &lt; input 遍历不同的行。使用冒号作为字段分隔符是通过 IFS=: 完成的。
可以编辑循环中的逻辑(我会调用一个函数),为了避免嵌套过多的 if 语句,我在标题行中使用了 continue

while IFS=: read -r StudentID FirstName LastName garbage; do
        if [ "$StudentID" = "StudentID" ]; then
                echo "StudentID:FirstName:LastName:hw1:"
                continue
        fi
        if [ "${FirstName}" = "Joe" ] && [ "${LastName}" = "Black" ] ; then
                echo "${StudentID}:${FirstName}:${LastName}:100:"
        else
                echo "${StudentID}:${FirstName}:${LastName}::"
        fi
done < input > input2

我将输出写入 input2,因为那将是问题 2 的输入。
只是为了计算 a 的乐趣,给了比利 100 / 4 的值。Jess 很幸运,他得到了 100!

while IFS=: read -r StudentID FirstName LastName hw1 garbage; do
        if [ "$StudentID" = "StudentID" ]; then
                echo "StudentID:FirstName:LastName:hw1:hw2:"
                continue
        fi
        if [ "${FirstName}" = "Bob" ] && [ "${LastName}" = "Billy" ] ; then
                (( newnumber = 100 / 4 ))
                echo "${StudentID}:${FirstName}:${LastName}:${newnumber}:50:"
        elif [ "${FirstName}" = "Not" ] && [ "${LastName}" = "Existing" ] ; then
                echo "${StudentID}:${FirstName}:${LastName}:77:50:"
        elif [ -n "${hw1}" ]; then
                echo "${StudentID}:${FirstName}:${LastName}:${hw1}:50:"
        else
                echo "${StudentID}:${FirstName}:${LastName}:100:50:"
        fi
done < input2

【讨论】:

  • 我把第一部分记下来了,但是我在处理第二部分时遇到了问题。我需要创建一个函数,可以将数据插入到标题字段匹配的任何字段中。 (在学生是 Jess 的标题字段 4 中插入一个成绩)。请记住,我仍然可以为任何学生输入新成绩。我只是无法输入现有作业的成绩。
  • 看看 Bob Billy 是如何被分配到 ${newnumber} 的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-28
  • 1970-01-01
  • 2011-09-26
  • 2015-07-11
  • 2017-02-10
相关资源
最近更新 更多