Reputation: 93
I'm trying to insert a string "abcd" at the position of 80 in each rows of a fixed length file.
Input file
1212121212121212121213231232345 00000003088 234235235321 MISS WAN
1212121212121212121213231232345 00000003088 324556346366 MISS NISCH
1212121212121212121213231232345 00000003088 547478657588 MISS RACHEL
1212121212121212121213231232345 00000009781 313156475788 MR & MRS ROCK
The length of each records are
awk '{print length}' temp.txt
74
76
77
79
I wasn't able to insert data at 80 and I've tried the below commands
sed "s/.\{80\}/&abcd/" test.txt
awk -vFS="" -vOFS="" '{$80=$80"abcd"}1' test.txt
I thought that I should first increase the length of the records so then I can use the above commands..
To insert spaces
sed -e "s/.\{75\}/& /g" test.txt
sed 's/$/ /" test.txt
Inside a loop
while read line
do
printf "$line " >>temp.txt
done <test.txt
Most of the time the above spaces get amended with the next lines and lost some of the contents as shown below..
4044046160710301740053062257440 00000003088 850052246976 MISS WAN
046160710301740053062257440 00000003088 850052246976 MISS NISCH
046160710301740053062257440 00000003088 850052246976 MISS RACHEL
2011888360797600140053062257440 00000009781 851011576287 MR & MRS ROCK
Expected answer:
4044046160710301740053062257440 00000003088 850052246976 MISS WAN abcd
4044046160710301740053062257440 00000003088 850052246976 MISS NISCH abcd
4044046160710301740053062257440 00000003088 850052246976 MISS RACHEL abcd
2011888360797600140053062257440 00000009781 851011576287 MR & MRS ROCK abcd
Any guidelines towards the right answer would be much appreciated.
Upvotes: 2
Views: 1384
Reputation: 20032
I can't see where you get stuck using
sed "s/$/ /" test.txt
and sed "s/.\{80\}/&abcd/" test.txt
.
How did you combine them? You don't want -i
for the first command, that would modify the inputfile.
Incorrect is
# error, did you try this:
sed "s/$/ /" test.txt | sed "s/.\{80\}/&abcd/" test.txt
The second sed
will not look at the output of the first command, but will start with the original test.txt
.
You can combine them (I also used single quotes) with
sed 's/$/ /' test.txt | sed 's/.\{80\}/&abcd/'
or shorter
sed 's/$/ /;s/.\{80\}/&abcd/' test.txt
The result might look good, but you can have additional spaces after abcd
. Better is
sed -r 's/$/ /;s/(.{80}).*/\1abcd/' test.txt
The first part of the comand is ugly. You can write your own loop like
while IFS= read -r line; do
printf "%-80sabcd\n" "${line}"
done < test.txt
This is a difficult method where you can use the simple awk
given by @karakfa.
Upvotes: 0
Reputation: 786111
You may use gnu awk
command:
awk -v RS='\r?\n' -v p='80' -v s='abcd' '{
pad=""; for (i=length(); i<=p; i++) pad=pad " "; print $0 pad s}' file
1212121212121212121213231232345 00000003088 234235235321 MISS WAN abcd
1212121212121212121213231232345 00000003088 324556346366 MISS NISCH abcd
1212121212121212121213231232345 00000003088 547478657588 MISS RACHEL abcd
1212121212121212121213231232345 00000009781 313156475788 MR & MRS ROCK abcd
Note use -v RS='\r?\n'
which sets record separator as optional \r
followed by \n
. This to address case when input file has DOS line breaks.
For loop starts from length of each line to desired position (being passed from command line in variable p
) and appends a space in pad
variable. Finally we print each row followed by padded space and new string.
Upvotes: 2
Reputation: 15039
Yet another way, combining karakfa's awk line, and the use of GNU wc
to get the maximum line length.
file="./your_file"
awk -v sp=4 -v max="$(wc -L "$file")" '{printf "%-"max+sp"s%s\n",$0,"abcd"}' "$file"
The -v
options initialize variables max
with the maximum line length in the file, and sp
for the number of spaces to use after the max line length.
Output:
4044046160710301740053062257440 00000003088 850052246976 MISS WAN abcd
046160710301740053062257440 00000003088 850052246976 MISS NISCH abcd
046160710301740053062257440 00000003088 850052246976 MISS RACHEL abcd
2011888360797600140053062257440 00000009781 851011576287 MR & MRS ROCK abcd
Upvotes: 0
Reputation: 67567
a simpler awk
$ awk '{printf "%-80s%s\n",$0,"abcd"}' file
1212121212121212121213231232345 00000003088 234235235321 MISS WAN abcd
1212121212121212121213231232345 00000003088 324556346366 MISS NISCH abcd
1212121212121212121213231232345 00000003088 547478657588 MISS RACHEL abcd
1212121212121212121213231232345 00000009781 313156475788 MR & MRS ROCK abcd
Upvotes: 3
Reputation: 133770
Solution as per OP's requirement for adding spaces as per length of 80: In case you have control M characters in your Input_files and you want to remove them then use:
tr -d '\r' < Input_file > temp_file && mv temp_file Input_file
then run following code:
awk -v var="80" '{printf("%s%"var-length($0)+1"s%s\n",$0,OFS,"abcd")}' Input_file
2nd solution(more generic one): Could you please try following, this solution will look for maximum length of the line in whole Input_file and will add spaces according to it and newly entered last field will be in same alignment with all other lines.
awk '
FNR==NR{
len=length($0)>len?length($0):len
next
}
{
printf("%s%"len-length($0)+1"s%s\n",$0,OFS,"abcd")
}
' Input_file Input_file
Upvotes: 2