5

I have a file with multiple lines/rows, and each line contains a variable amount of columns:

Name1 String111 String112
Name2 String121 String122 String123
Name3 String131 String132 String133 String134

And so on and so forth (no pattern as to what line has how many entries). I would like to add the name in the first column to the beginning of every column in that line/row such that I end up with:

Name1 Name1String111 Name1String112
Name2 Name2String121 Name2String122 Name2String123
Name3 Name3String131 Name3String132 Name3String133 Name3String134

We can start it simple and get more complicated:

How to add a string such as "Test" to the beginning of every column?

How to add the value in column 1 to every column in that row, including column 1?

How to add the value in column 1 to every column in that row, not including column 1?

My best guesses:

I do not know how to call "every column" and I do not know how to make the command access the currently column so I can only add a string or the value in column 1 to a single other column:

awk -F'\t' -vOFS='\t' '{ !$1 = "hello" $2}' 
awk -F'\t' -vOFS='\t' '{ !$1 = $1 $2}' 

Is there a good resource on where I can learn this syntax?

0
10

Just iterate over all fields starting with the second, and concatenate the first field to whatever you already have:

$ awk '{ for(i=2;i<=NF;i++){ $i = $1$i }}1' file
Name1 Name1String111 Name1String112
Name2 Name2String121 Name2String122 Name2String123
Name3 Name3String131 Name3String132 Name3String133 Name3String134

The 1 in the end is awk shorthand for "print the current line". You could write the same thing like this:

$ awk '{ for(i=2;i<=NF;i++){ $i = $1$i }; print}' file
Name1 Name1String111 Name1String112
Name2 Name2String121 Name2String122 Name2String123
Name3 Name3String131 Name3String132 Name3String133 Name3String134

The basic idea above can be trivially expanded to match all of your examples. NF is the special awk variable that holds the number of fields; it will always be set to however many fields are present in the current line. Then, awk allows you to refer to specific fields using a variable. So if you set i=5, then $i is equivalent to $5. This then lets you iterate over all fields using the for(i=2;i<=NF;i++) { } format which sets i to all numbers from 2 to the number of fields on this line.

0
4

If your first field can't contain & then all you need is:

$ awk '{gsub(/[[:space:]]+/,"&"$1)}1' file
Name1 Name1String111 Name1String112
Name2 Name2String121 Name2String122 Name2String123
Name3 Name3String131 Name3String132 Name3String133 Name3String134
2

In any awk:

awk '{ OFS=" "$1; $1=$1 }1' infile

this sets OFS to <SPC><first-column's-value> then re-evaluate the fields based on the OFS by $1=$1 then print (see awk idiom 1).

can be written also as following

awk '{ OFS=" "$1 } $1=$1' infile

... but then that would fail for the lines that first field is 0; here we can use empty string "" to force awk for string assignment, so the result of $1=$1"" would always evaluate true and so result of assignment would be true then default print action will be triggered for those lines as well:

awk '{ OFS=" "$1 } $1=$1""' infile

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.