Search code examples
macosfileunixprepend

Delete N lines & prepend M lines in each file matching a pattern, recursively


I'm asking for help with optimizing the following command, but also writing it here for reference if it might help anyone in the future.

I wanted to go through all .swift files in the current folder and continue recursively with files in any and all subfolders and then do:

  1. Delete the N (below 7) first lines in each file
  2. Prepend, not append, multiple lines, containing characters that otherwise might need escaping (such //)

Solution

  • The solution I came up with is inspired by this answer and has been approved thanks to @EdMorton 👏, but reading the multiline text to prepend from a file instead of echoing a string.

    This might only work if you have no space in your paths.

    Solution

    You can copy paste this into the terminal, replace 8, with how many lines you would like to remove and also replace ~/Desktop/TextToPrepend.txt with the path to your file with the contents that you would like to prepend.

    find . -name '*.swift' | while IFS= read -r f; do
        cp ~/Desktop/TextToPrepend.txt tmpfile &&
        tail -n +8 "$f" >> tmpfile && 
        mv tmpfile "$f"
    done
    

    Improvements?

    It would be even nicer to allow for space n paths and not have to use a file, but rather an in place multiple-line solution, but I ran into issues with a newline and escaping //.

    Use case

    I just used this to replace the file header for ALL Swift files in an open source iOS Zilliqa wallet called "Zhip".

    The standard for file headers in Xcode is to start each line with a comment //.

    Pro-tip

    Start your project by add the file IDETemplateMacros.plist as suggested by this guide.