Editing a file with a script (using vi?)

  • Thread starter fluidistic
  • Start date
  • Tags
    File
In summary, the a open source chess engine called Stockfish is regularly updated with new features. A user wishes to include a new feature in their script of auto editing the code of Stockfish before compiling, but does not know how to use vi or a similar program. There are several ways to do this using a command line based editor like ex, but the user is not familiar with vi and is not sure if it supports regular expressions. Alternatives like sed or awk are not necessarily better or worse - just different. The user is done with this task because the changes they wanted to make are not likely to improve the strength of the program.
  • #1
fluidistic
Gold Member
3,923
261
Hello guys!
There's an open source chess engine (Stockfish) that I really like and I always want the latest version. The project is so active that there's approximately a new version every day. I decided to make a script that auto downloads the code, auto compile Stockfish, auto move the executable to a folder I want, auto rename another file (for the settings of the engine) and auto remove the unnecessary files and folders. I have succeeded in doing this.
However I wish to include a new part in my script: I want to edit the code of Stockfish (a file more precisely, called endgame.cpp) prior to compiling it, but I don't know how to use "vi" nor a similar program to do so. In fact I don't even know programming.

Because the project is very active, they may modify endgame.cpp and so the lines I want to modify may not be "constant". I.e. maybe today I want to modify lines 25 to 32 but tomorrow this would be lines 37 to 44.

More precisely, I want to comment the lines
Code:
add<KPK>("KPK");
add<KNNK>("KNNK");
add<KBNK>("KBNK");
add<KRKP>("KRKP");
add<KRKB>("KRKB");
add<KRKN>("KRKN");
add<KQKP>("KQKP");
add<KQKR>("KQKR");

add<KNPK>("KNPK");
add<KNPKB>("KNPKB");
add<KRPKR>("KRPKR");
add<KRPKB>("KRPKB");
add<KBPKB>("KBPKB");
add<KBPKN>("KBPKN");
so that the new/modified code would look like:
Code:
//  add<KPK>("KPK");
//  add<KNNK>("KNNK");
//  add<KBNK>("KBNK");
//  add<KRKP>("KRKP");
//  add<KRKB>("KRKB");
//  add<KRKN>("KRKN");
//  add<KQKP>("KQKP");
//  add<KQKR>("KQKR");

//  add<KNPK>("KNPK");
//  add<KNPKB>("KNPKB");
//  add<KRPKR>("KRPKR");
//  add<KRPKB>("KRPKB");
//  add<KBPKB>("KBPKB");
//  add<KBPKN>("KBPKN");

I have done some google searches but I don't really know how to do it. I guess I'd have to type a command to "search" a line, comment it, "search" another line, comment it, etc. until the last line and then "save" the file.
Any help is appreciated, thank you!
 
Technology news on Phys.org
  • #2
I'm not familiar with vi, but I would check to see if it supports regular expressions. If so, what you want it to do is to search for any line of code that starts with "add<K" and ends with ";" and replace it with the same string with "//" appended to the front. That's where I would start.
 
  • #3
Do you want or need to use vi?
In vi you can do search and replace by going into command mode by typing : (so shift and the ":" key)
you can then type %s/search/replace
where search is for example add< and replace is \/\/ add<

note that the for-slash and backslash sign is special. They are used for instance to separate the search string from the replace string . To make them unspecial, just put a backslash in front of it. However, if you are making a script, you are probably better off doing this with a sed, awk or perl command in your script.
 
  • #4
You should be able to do this with a single sed command in your script. Try a Google search on "sed global search and replace". You'll get dozens of hits.
 
  • #5
vi is just a visual interface (hence the name) to a command line based editor called ex, which should also be on any unix system.

Any command preceded by a : in vi is actually running ex.

Running ex in a script, using input that is part of the script, is no problem - that's what it was written for.

Alternatives like sed or awk are not necessarily better or worse - just different, IMO.
 
  • #6
Alternatively, you can use the unix tool "diff" to create a difference file and "patch" to merge the difference file into a new version.
 
  • #7
Thanks a lot guys.
No, I am not forced at all to use vi, I thought about vi but now that I've read about sed, it looks like much easier. I have tried some commands like
Code:
sed s/add<KPK>("KPK");/ / <old >new
and some variants of that but I always got errors, for example due to the "(".
Anyway I am done with this task, not because I have have/not succeeded in doing it but because the changes I wanted to do in the code are likely not improving the strength of the program (noticeably at least). I've tested it against the normal non modified version and it scored 53 wins, 57 losses and 191 draws. This doesn't mean that it's weaker, what it means is that the change in elo is so small that I'd need around 50k games to determine which version is stronger. So in the end my modification is not worth it.
Actually the result I got translate into -4.6 elo for my version (I don't have the error bars). And the likelihood of superiority (i.e. the chance that my version is stronger than the original one) is 0.35.
 
  • #8
fluidistic: vi and ex editors are generally better for interactive editing, whereas the sed editor and awk command are better for noninteractive editing. In your case, you want noninteractive editing. Even though you do not need it now, your sed command in post 7 was close to correct, and instead should be,

sed 's/add<KPK>("KPK");/ /' <old >new​

I probably would use the following, instead, if I were going to use sed. Here I used at-sign (@) as the delimiter, but you can use any character you prefer for the delimiter character. The input file is in01.

Code:
sed -e '\@add<KPK>("KPK");@s@^@// @' \
   -e '\@add<KNNK>("KNNK");@s@^@// @' in01

Here is another way to do it, using awk. Type the following code into a file named, e.g., myprog01.sh.

Code:
#!/bin/sh
# myprog01.sh - Bourne shell program to comment out certain records. The
#    given string can begin in any column.
# Created:  2014-03-09, nvn.
# Usage:  sh myprog01.sh infile outfile
awk '
   {line01=$0;}
   /add<K/ {
      if(index($0,"add<KPK>(\"KPK\");")>0)line01="// "$0;
      else if(index($0,"add<KNNK>(\"KNNK\");")>0)line01="// "$0;
      else if(index($0,"add<KBNK>(\"KBNK\");")>0)line01="// "$0;

      else if(index($0,"add<KNPK>(\"KNPK\");")>0)line01="// "$0;
      else if(index($0,"add<KNPKB>(\"KNPKB\");")>0)line01="// "$0;
      else if(index($0,"add<KRPKR>(\"KRPKR\");")>0)line01="// "$0;
      }
   {print(line01);}
   ' $1 > $2
exit

Next, if your input is in a file named in01, then issue the following command at the linux bash shell prompt. The output from this command will be written (overwritten, caution) to file out01.

sh myprog01.sh in01 out01​
 
Last edited:
  • #9
Using diff and patch it is:

Code:
diff -u orig/endgame.cpp mod/endgame.cpp > endgame.patch
patch new/endgame.cpp < endgame.patch

In particular, patch will make sure the change succeeds completely without surprises.
If the new endgame.cpp does not match any more due to more structural changes, patch will give an informational error, meaning you will have to do some manual work.Using perl (which I favor over sed and awk) it is for instance:
Code:
perl -pi -e '
  s#(add<KPK>("KPK");)#// $1#;
  s#(add<KNNK>("KNNK");)#// $1#;
  ...' endgame.cpp
 

1. What is vi and why is it used for editing files with a script?

Vi is a command-line text editor that is commonly used for editing files with a script. It is preferred by many programmers and scientists because it is lightweight and can be used on remote servers without a graphical user interface.

2. How do I open a file for editing using vi?

To open a file for editing in vi, you can type the command "vi" followed by the name of the file you want to edit. If the file does not exist, vi will create a new file with that name. If the file already exists, vi will open it for editing.

3. What are some basic commands for editing a file with vi?

Some basic commands for editing a file with vi include:

  • To insert text: press "i" to enter insert mode, type your text, then press Esc to return to command mode.
  • To save changes: press ":" to enter command mode, then type "w" to write changes to the file or "wq" to write changes and quit vi.
  • To delete text: press "x" to delete the character under the cursor, or "dd" to delete the entire line.
  • To move around the file: use the arrow keys or "h" (left), "j" (down), "k" (up), and "l" (right).

4. Can I undo changes made in vi?

Yes, you can undo changes made in vi by pressing "u" in command mode. This will undo the most recent change. You can also use the command "U" to undo all changes made on the current line.

5. How do I exit vi without saving changes?

To exit vi without saving changes, you can press ":" to enter command mode, then type "q!" to force quit vi without saving. This will discard any changes made since the last save.

Similar threads

  • Programming and Computer Science
Replies
20
Views
512
  • Programming and Computer Science
Replies
2
Views
367
  • Programming and Computer Science
Replies
9
Views
3K
  • Programming and Computer Science
Replies
3
Views
4K
  • Programming and Computer Science
Replies
19
Views
1K
  • Programming and Computer Science
Replies
10
Views
1K
  • Programming and Computer Science
Replies
5
Views
1K
  • Programming and Computer Science
3
Replies
75
Views
4K
  • Programming and Computer Science
Replies
11
Views
2K
  • Programming and Computer Science
Replies
1
Views
1K
Back
Top