Search code examples
regexfile-iojuliapcre

what is the correct way to find replace content of a file in julia?


I am trying to comment all the ids except the required id of a file.

content of ids.txt:

name="app1"
id="123-45-678-90"
#id="234-56-789-01"
#id="345-67-890-12"
#id="456-78-901-23"
#id="567-89-012-34"
#id="678-90-123-45"

content of write_correct_id.jl:

#required id
req_id = "id=\"456\-78\-901\-23\""

#read file content to array
ids_array
open("/path/to/ids.txt", "r") do ids_file
ids_array = readlines(ids_file)
end

#comment all lines starting with "id =" and un-comment the line with required id
id_pattern ="^id="
id_regex = Regex(id_pattern)

for line in ids_array
if occursin(id_regex, line)
replace (line, "id" => "#id")
elseif occursin(req_id, line)
replace(line, "#$req_id" => "req_id)
end
end

#write back the modified array to the file
open("/path/to/ids.txt", "w") do ids_file
for line in ids_array
write("$line\n")
end
end

The elements starting with id (ie.^id=) are not recognised.

please help me!


Solution

  • The problem with your code that strings are immutable in Julia so replace does not mutate a string but creates a new one.

    Here is my proposal how I would write your code (note some other small differences in my implementation e.g. count makes sure we only make one substitution as in general there might be multiple occurrences of the pattern in some line; also startswith should be in general faster than occursin in your use case):

    req_id = "id=\"456-78-901-23\""
    id_pattern = "id="
    
    lines = readlines("idx.txt")
    
    open("idx.txt", "w") do ids_file
        for line in lines
            if startswith(line, "#$req_id")
                println(ids_file, replace(line, "#$req_id" => req_id, count=1))
                # or even:
                # println(ids_file, chop(line, head=1, tail=0))
            elseif startswith(line, id_pattern)
                println(ids_file, replace(line, "id" => "#id", count=1))
                # or even:
                # println(ids_file, "#"*line)
            else
                println(ids_file, line)
            end
        end
    end