简体   繁体   English

在Unix中使用SED / AWK将数据附加到特定的行号

[英]Append Data to a specific line number using SED/AWK in Unix

I have a file separated by colons that looks like this.. 我有一个用冒号分隔的文件,如下所示。

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

The first line will always contain the header. 第一行将始终包含标题。 Let's say each field after the 3rd in all rows will contain grades. 假设所有行中第3个字段之后的每个字段都包含成绩。

Let's say I add hw1 to only Joe Black since he completed it early. 假设我将hw1 添加到Joe Black,因为他很早就完成了。

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

First Question) 第一个问题)

How would I append to the end of the a line when I have the line number to certain lines, or append to all lines but with different data (colons, the grade, or the assignment as above)? 当我在某些行中具有行号时,或者在具有不同数据(分号,成绩或如上所述的作业)的所有行中附加行号时,如何在行的末尾附加?

Second Question) 第二个问题)

How would I add data into those newly created fields for the other students. 我如何将数据添加到其他学生的那些新创建的字段中。 Add the grade for hw1 for Bob and Jess if there are more grades in the file. 如果文件中还有更多成绩,请为Bob和Jess添加hw1的成绩。 ex.. 例如

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:

I'm assuming I can only use Awk since sed will go through every line. 我假设我只能使用Awk,因为sed将遍历每行。

gawk 高克

question 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::

question 2: 问题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:

You can do it without awk. 你可以不用awk就可以做到。 When data is stored in the file input, you can loop over different lines with while read -r fields; do .. done < input 当数据存储在文件输入中时,可以使用while read -r fields; do .. done < input遍历不同的行while read -r fields; do .. done < input while read -r fields; do .. done < input . while read -r fields; do .. done < input Using a colon as a fieldsep is done with IFS=: . 通过IFS=:将冒号用作fieldsep。
The logic within the loop can be edited (I would call a function), for avoiding to much nested if-statements I used a continue for the header line. 可以编辑循环中的逻辑(我将调用一个函数),以避免在嵌套很多的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

I wrote the output to input2, since that wil be the input for question 2. 我将输出写到input2,因为那将是问题2的输入。
Just for the fun of calculating a gave Billy the value 100 / 4. Jess is lucky, he gets 100 ! 仅出于计算给比利100/4的乐趣。杰西很幸运,他得到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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM