Example:
O o x
[
2 A X
3 B X
4 C X
5 D X
6 E Z
7 F Z
a b c 12d
]
What I would like to do is to rename the first column of the above file without affecting the format. The output should look like the following:
Output:
O o x
[
1 A X
2 B X
3 C X
4 D X
5 E Z
6 F Z
a b c 12d
]
#! /bin/ksh
cd $HOME/lib/.Lee
#nl = no. of lines.
nl=`grep 'X' ex | wc -l`
#ln = line no.
ln=1
$1=NR
until [[ "$ln" = "$nl" ]]; do
awk '{$1 = NR; print}' ex
ln=ln+1
done
The above script affects the format and the results keep on and on and on.
awk -v no=1 ' /\[/,/\]/ { if ( $0 ~ "^[0-9]+ " ) { sub("^[0-9]+ ",no" ");no++}}; 1 ' filename
amon
May 16, 2007, 5:47am
3
anbu can we have some awk code explanation..I am confused..but I like this topic
thanks in advance
/\[/,/\]/ { ... } This block is executed for lines between [ and ]
$0 ~ "+ " Checks whether first field is a number
sub("+ ",no" ") If above condition is true replace first field by the value in variable "no" and increment the variable "no"
1 which means true and prints the line
amon
May 16, 2007, 8:03am
5
thanks for nice explanation..
Thanks for the reply. I tried using the script you gave but showed the following messages:
awk: syntax error at source line 1
awk: bailing out at source line 1
So, I tried few other things but gave the same results. What I want to do exactly is to renumber only the first column where X are found.
Regards.
ilak1008:
Thanks for the reply. I tried using the script you gave but showed the following messages:
awk: syntax error at source line 1
awk: bailing out at source line 1
So, I tried few other things but gave the same results. What I want to do exactly is to renumber only the first column where X are found.
Regards.
Use nawk to avoid this error.
Do you mean the X in third field? Then try this
nawk -v no=1 ' /\[/,/\]/ { if ( $0 ~ "^[0-9]+ " && $3 == "X" ) { sub("^[0-9]+ ",no" ");no++}}; 1 ' filename
Try that:
awk '/^\[/,/^]/ { if ($3 == "X") $1=++line } 1' filename
Jean-Pierre.
Hello Anbu23!
The code you gave worked fine.
I tried to use similar nawk command to the file below but nothing happened.
nawk -v no=1 ' /M_I : \[/,/\]/ { if ( $1 ~ "^[0-9]+ " && $7 == "HI" ) { sub("^[0-9]+ ",no" ");no++}}; 1 ' filename
Contents of "filename":
D : [
# ===========
]
S : [
# ============
Nb_S_I : 5
S_I : [
# R_L "S_D"
56 "1-2x"
48 "1-2x"
40 "1-2x"
32 "1-2x"
24 "1-2x"
]
]
M_I : [
# ===========
# M_I B_T S_Nb C_Nb L_N P_Nb O M_I A_F D_F
4 X 9 1 2 4 HI 1 F F
5 F 2 1 4 0 HI 1 F F
6 F 4 1 6 0 HI 1 F F
10 L 1 1 8 4 HI 1 F F
]
The output should be as follows:
D : [
# ===========
]
S : [
# ============
Nb_S_I : 5
S_I : [
# R_L "S_D"
56 "1-2x"
48 "1-2x"
40 "1-2x"
32 "1-2x"
24 "1-2x"
]
]
M_I : [
# ===========
# M_I B_T S_Nb C_Nb L_N P_Nb O M_I A_F D_F
1 X 9 1 2 4 HI 1 F F
2 F 2 1 4 0 HI 1 F F
3 F 4 1 6 0 HI 1 F F
4 L 1 1 8 4 HI 1 F F
]
aigles
May 19, 2007, 4:17am
10
The field $1 can't contain a space that is a separator.
Change your test :
nawk -v no=1 ' /M_I : \[/,/\]/ { if ( $0 ~ "^[0-9]+ " && $7 == "HI" ) { sub("^[0-9]+ ",no" ");no++}}; 1 ' filename
The nawk program can be simplified:
nawk '/M_I : \[/,/\]/ { if ( $0 ~ /^[0-9]\+ / && $7 == "HI" ) $1 = ++no }; 1 ' filename
Jean-Pierre.
I have attached a sample file about the actual format of the lines I want its line numbers changed.
I used the following script to change the line numbers:
#! /bin/ksh
cd $HOME/lib
nawk -v no=1 ' /Marker_Item : \[/,/\]/ { if ( $5 == "HIGH" ) {sub($1,no);++no}}; 1 ' filename
As you noticed at the results, the alignment for lines 7, 8 and 9 has changed. Any ideas on how to realign it?
Thanks!
if you have Python, here's an alternative;
flag = False
num=1 # renaming counter
for line in open("file"):
line = line.strip()
if line.startswith("M_I : ["): flag = True
if flag:
l = line.split()
try:
if l[0].isdigit():
l[0]=str(num)
num+=1
except:pass
print " ".join(l)
else:print line
if line.startswith("]"):
flag = False
output:
# ./test.py
D : [
# ===========
]
S : [
# ============
Nb_S_I : 5
S_I : [
# R_L "S_D"
56 "1-2x"
48 "1-2x"
40 "1-2x"
32 "1-2x"
24 "1-2x"
]
]
M_I : [
# ===========
# M_I B_T S_Nb C_Nb L_N P_Nb O M_I A_F D_F
1 X 9 1 2 4 HI 1 F F
2 F 2 1 4 0 HI 1 F F
3 F 4 1 6 0 HI 1 F F
4 L 1 1 8 4 HI 1 F F
]
I'm sorry ghostdog74 'coz I just use ksh shell.
Thanks for your help anyway.
anbu23
May 21, 2007, 1:56am
14
ilak1008:
I have attached a sample file about the actual format of the lines I want its line numbers changed.
I used the following script to change the line numbers:
#! /bin/ksh
cd $HOME/lib
nawk -v no=1 ' /Marker_Item : \[/,/\]/ { if ( $5 == "HIGH" ) {sub($1,no);++no}}; 1 ' filename
As you noticed at the results, the alignment for lines 7, 8 and 9 has changed. Any ideas on how to realign it?
Thanks!
nawk ' /Marker_Item : \[/,/\]/ {
if ( $5 == "HIGH" ) {
str=$0;
sub($1".*",$1,str);
sub(" *"$1,sprintf("%*d",length(str),++no))
}
}; 1 ' filename
anbu23:
nawk ' /Marker_Item : \[/,/\]/ {
if ( $5 == "HIGH" ) {
str=$0;
sub($1".*",$1,str);
sub(" *"$1,sprintf("%*d",length(str),++no))
}
}; 1 ' filename
anbu23, could you please explain the above script?
Thanks!
vino
May 21, 2007, 2:25am
16
ilak1008:
Example:
O o x
[
2 A X
3 B X
4 C X
5 D X
6 E Z
7 F Z
a b c 12d
]
What I would like to do is to rename the first column of the above file without affecting the format. The output should look like the following:
Output:
O o x
[
1 A X
2 B X
3 C X
4 D X
5 E Z
6 F Z
a b c 12d
]
#! /bin/ksh
start=0
begin=0
while IFS=" " read first rest
do
if [[ $first = *\[* ]] ; then
begin=1
elif [[ $first = *\]* ]] ; then
begin=0
fi;
if [[ $begin == 1 ]]; then
if [[ $first = *[123456789]* ]] ; then
((start=start+1))
first=${start}
fi;
echo ${first}${IFS}${rest}
elif [[ $begin == 0 ]]; then
echo ${first}${IFS}${rest}
fi;
done < input.file
anbu23
May 21, 2007, 2:37am
17
sub($1".*",$1,str) Remove other than first field in str
sprintf("%*d",length(str),++no) Form a new string with the same format of first field. * is for field length and gets the value from length(str)
sub(" *"$1,sprintf("%*d",length(str),++no)) Substitute first field in $0 by the newly formed string.
The alignment for lines 7, 8 and 9 has changed because previously there was a two digit number. In above code we used length of first field and used sprintf to align it properly.
anbu23:
nawk ' /Marker_Item : \[/,/\]/ {
if ( $5 == "HIGH" ) {
str=$0;
sub($1".*",$1,str);
sub(" *"$1,sprintf("%*d",length(str),++no))
}
}; 1 ' filename
ANBU23, it works perfectly now. Thanks for all the help.
And to aigles, ghostdog74 and vino, thank you, too, for your suggestions.