Reputation: 71
I want to do as follows in a .txt file. Contents of file.txt are:
w|x|y|z
w1|x1|y1|z1
w2|x2|y2|z2
Required result:
w|x|y|z|w_x
w1|x1|y1|z1|w1_x1
w2|x2|y2|z2|w2_x2
I wish to append the first two pipe seperated words to be appended at the end of each line with a underscore(_) between them in the same file.
Upvotes: 0
Views: 55
Reputation: 241828
You can use sed:
sed 's/^\([^|]*\)|\([^|]*\).*/&|\1_\2/' file.txt
# ~~~~~ ~~~~~ ~~ ^ ^ ^
# 1st 2nd Rest | | |
# column column All 1st|
# 2nd
or Perl:
perl -plaF'/\|/' -e '$_ .= "|$F[0]_$F[1]"' -- file.txt
-p
reads the input line by line and prints the output-l
removes newlines from input and adds them to output-a
split input into the @F array-F
specifies the separator for -a
Upvotes: 4
Reputation: 1464
Using purely bash text processing simple commands:
cut -d '|' -f 1,2 --output-delimiter='_' t.txt | paste -d '|' t.txt -
If your data is in t.txt
file.
Explanation:
cut
) takes 1st and 2nd column from file and joins them with '_' (output delimiter)paste
joins original file with output from the previous command, line by line, using '|' delimiter (notice -
mark which is used as standard input taken from piped data from cut
command)Upvotes: 1
Reputation: 212238
The "advantage" of perl and (gnu) sed is that they offer an option to overwrite the file with the output, which seems to be the OPs desire. The disadvantage is that they offer such an option which prevents the user from appreciating that such a thing is not the Unix Way (TM). Do this with awk, and use the shell to redirect the output as desired (eg, write a temp file and move it if desired).
awk '{print $0,$1 "_" $2}' OFS=\| FS=\| file.txt
Upvotes: 1