Score:0

How to copy partial contents (specifically few sections denoted by square brackets) from one file to another with shell script?

et flag

I have one project's .git/config file in which I have following contents:

[user]
    name = <FullName>
    email = <EmailID>
    username = <UserName>
[core]
    editor = nvim
    whitespace = fix,-indent-with-non-tab,trailing-space,cr-at-eol
    pager = delta
[web]
    browser = google-chrome
....
....
[alias]
    a = add --all
    ai = add -i
    #############
    ap = apply
    as = apply --stat
    ac = apply --check
....
....
[filter "lfs"]
    clean = git-lfs clean -- %f
    smudge = git-lfs smudge -- %f
    process = git-lfs filter-process
    required = true

Now I want to copy multiple sections and their contents like [alias], [filter "lfs"] etc. but not the [user] and [web] sections from this .gitconfig file to another project's (which is under same parent as this project's directory) .gitconfig file.

Now I know I can loop thro' and print lines of this file, but not idea how to write multiple sections to another file(with less code clutter as possible) such that it doesn't overwrite target file's original contents:

while read line || [ -n "$line" ]; do echo $line; done < $filename;

Help is much appreciated...

Score:2
nl flag
P.P

While you could do this via bash/awk, I'd recommend using an INI file parser. For example, you can do the following in Python using configparser library:

import sys
import configparser

def print_section(conf, section):
    print("[{}]".format(section))
    for key in conf[section]:
        print("    {} = {}".format(key, conf[section][key]))


c = configparser.RawConfigParser()
c.read('config.ini')

sections = ['alias', 'filter "lfs"']
for s in sections:
    print_section(c, s)

Oneliner of the same:

printf "import sys; import configparser; c = configparser.RawConfigParser(); c.read('config.ini'); sections = ['alias', 'filter \"lfs\"'];\nfor s in sections:\n  print(\"[{}]\".format(s));\n  for key in c[s]:\n    print(\"    {} = {}\".format(key, c[s][key]))"  | python3
et flag
Your answer in Python is good, but can you also specify how can I do this in Awk/Sed ? I would really like to add it to Shell script that I have already created
P.P avatar
nl flag
P.P
@VickyDev It's really not worth the pain to do it in shell. If you're looking to integrate this into a script (or run from cmdline), you can run the same as a oneliner - updated the answer.
et flag
Ok, if I write it to file using python like `with open(...)` and then `fwrite` append, how can I force newline when every next line(of section, means section title then newline and then section content line by line exact structure) is being written ?
et flag
Right now with basic `fwrite` it's writing 4 spaces instead of next line with indentation, how do I solve that?
P.P avatar
nl flag
P.P
@VickyDev The code in the answer does format the sections. Isn't that work for you?
et flag
About printing is fine, but as I've asked in question, I want it to be written/appended to another file. The format just places the text as it is with equals sign but it doesn't work when writing with newlines and indentation on each line of 4 spaces initially
P.P avatar
nl flag
P.P
@VickyDev I am not sure I understand your question. If you want to append to another file, can you not redirect the onliner `... | python3 >> another_file` or `... | python3 > another_file` to overwrite?
et flag
Oh sorry, was thinking only about f.write, but yes that works too, accepted.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.