Skip to main content

✏️ Editing Files Tools

Utilities for editing files.


savestate

Records a file’s current state into a variable.

ArgumentDescription
VARVariable to store state
FILEFile to check
savestate test /system/build.prop
update_file_string "ro.product.system.model=Just Test" /system/build.prop
savestate test2 /system/build.prop

if [[ "$test" == "$test2" ]]; then
ui_print "build.prop was not edited"
else
ui_print "build.prop changed"
fi

patch_fstab

Replaces properties in fstab files.

ArgumentDescription
LINEPattern to find line
PROPProperty to find
NEWNew property value
FILEFstab file
# Replace fileencryption=ice with encryptable in userdata line
patch_fstab userdata "fileencryption" "encryptable" "/vendor/etc/fstab.qcom"

update_file

Supports: _addon _zip

Updates existing prop lines in a file.

ArgumentDescription
SRCFile with new props
DESTDestination file
-forceIf any of the new props do not exist in the destination file, ensure they are added to the end
# Only props that already exist in the destination file will be updated
update_file "NewPropLines.txt" "/system/build.prop"

# Ensures to add all the props even if they do not exist in the destination file
update_file -force "NewPropLines.txt" "/system/build.prop"

update_file_string

Updates prop lines directly with strings.

ArgumentDescription
LINELine(s) to update
FILEDestination file
-forceIf any of the new props do not exist in the destination file, ensure they are added to the end
# Only props that already exist in the destination file will be updated
update_file_string "ro.product.system.model=NEW MODEL" /system/build.prop

# Ensures to add all the props even if they do not exist in the destination file
update_file_string -force "ro.product.system.model=NEW MODEL" "ro.product.system.name=NEW NAME" "ro.build.display.id=NEW ID" /system/build.prop

xml_kit

Edits XML files by targeting specific sections.

ArgumentDescription
-open START ENDStart and end tags of XML section (multiple allowed)
-in PATTERNPattern to filter section
-change-value ATTR VALChange attribute value (ATTR="VAL")
-change-tag TAG VALChange value between tags (<TAG> VAL </TAG>)
-change-content OLD NEWReplace text in section
-add TEXTAdd text after section
-add-inside TEXTAdd text inside section
-after-line LINE TEXTAdd text after line
-before-line LINE TEXTAdd text before line
-get-valueReturns the current content of the section without including opening and closing tags.
-removeRemoves the entire current section of the last -open done
-printPrint full result instead of editing
-print-resultSimilar to -print but only prints the modified -open sections without merging them into the rest of the structure.
-no-auto-spacesDisable auto-spacing
FILEXML file to edit

Test.xml

<users version="1.0">
<user id="1234">
<name>BlassGO</name>
<age>22</age>
</user>

<user id="5678" isAdmin="true">
<name>Ismael</name>
<age>22</age>
</user>

<user id="9123"/>
</users>
# Open section
xml_kit -open 'users' 'users' /sdcard/Test.xml

# Nested sections
# If modifications are not specified only the sections that matches are printed.
xml_kit -open 'users' 'users' -open 'user' 'user' /sdcard/Test.xml

# Open sections with self-closing tags
# Only sections with the specified closure are considered
xml_kit -open 'users' 'users' -open 'user' '/>' /sdcard/Test.xml # Only user id="9123"

# Filter sections by an attribute, regardless of its value
# The order of the attributes doesn't matter
xml_kit -open 'users' 'users' -open 'user isAdmin' 'user' /sdcard/Test.xml

# Filter sections by an attribute value
xml_kit -open 'users' 'users' -open 'user id="5678"' 'user' /sdcard/Test.xml

# Change attribute
xml_kit -open 'users' 'users' -open 'user id="5678"' 'user' -change-value id "NEW_ID" /sdcard/Test.xml

# Change tag value
xml_kit -open 'users' 'users' -open 'user id="1234"' 'user' -change-tag name "Just me" /sdcard/Test.xml

# Add text
xml_kit -open 'users' 'users' -open 'user id="1234"' 'user' -add "Just Test" /sdcard/Test.xml

# Add text inside
# If a filtering is not applied, the changes will be applied to all macthes
xml_kit -open 'users' 'users' -open 'user' 'user' -add-inside "Add me in all users" /sdcard/Test.xml

# After line
xml_kit -open 'users' 'users' -open 'user' 'user' -after-line "BlassGO" "Just Test" /sdcard/Test.xml

# Before line
# The -in parameter searches for matches throughout the entire section
xml_kit -open 'users' 'users' -open 'user' 'user' -in Ismael -before-line "<age>" "Just Test" /sdcard/Test.xml

# Get the content of a section
user_name=$(xml_kit -open 'users' 'users' -open 'user id="5678"' 'user' -open 'name' 'name' -get-value /sdcard/Test.xml)
ui_print "The user name is: $user_name" # Ismael

# Get the content of all sections
user_names=$(xml_kit -open 'users' 'users' -open 'user' 'user' -open 'name' 'name' -get-value /sdcard/Test.xml)
ui_print "The user names are: $user_names" # BlassGO, Ismael

# Remove section
# The entire user section with id 1234 will be removed
xml_kit -open 'users' 'users' -open 'user id="1234"' 'user' -remove /sdcard/Test.xml
info

It supports tags with attributes that span multiple lines, which is common for readability. However, these line breaks are not guaranteed to be preserved.

note

-in + -get-value case:

When you use the -in parameter, it searches for a match within the content of the deepest open section. This is where the conflict with -get-value happens. Typically, -get-value is also used to retrieve content from the deepest open section. This causes -in to apply its filter directly to the value of the segment you're trying to retrieve. While this can be useful if you're trying to partially match a value, for most cases, it's best to use the native attribute filter.


add_lines

Supports: _addon _zip

Adds lines from multiple files to a destination file.

ArgumentDescription
-after-line LINEAdd after this line (multiple allowed)
-before-line LINEAdd before this line (multiple allowed)
SRCSource file(s)
DESTDestination file
add_lines "Add.txt" /system/build.prop
add_lines "Add.txt" "Add2.txt" "Add3.txt" /system/build.prop
add_lines -after-line "Some line" "Add.txt" /system/build.prop
add_lines -before-line "Some line" "Add.txt" /system/build.prop
add_lines -after-line "Some line" "Add.txt" -after-line "Some line 2" "Add2.txt" -before-line "Some Line 3" "Add3.txt" /system/build.prop

add_lines_string

Adds lines directly as strings to a file.

ArgumentDescription
-after-line LINEAdd after this line (multiple allowed)
-before-line LINEAdd before this line (multiple allowed)
LINELine(s) to add
DESTDestination file
add_lines_string "New line" "New line 2" /system/build.prop
add_lines_string "" /system/build.prop # Empty line
add_lines_string -after-line "Some line" "add this after" -after-line "Some line 2" "add this after" /system/build.prop
add_lines_string -before-line "Some line" "add this before" -before-line "Some line 2" "add this before" /system/build.prop
add_lines_string "New line" " " "New line 2" " " /system/build.prop

replace

Replaces text in a file or directory.

ArgumentDescription
OLDText to replace
NEWReplacement text
PATHFile or directory
-rRecursive (whole directory)
-aReplace entire line containing text
-only-firstJust replace the first coincidence (if used -r this applies to each file, not only the first)
-follow-symlinksFollow Symlinks especially when used -r
-bytesHow many bytes read for the check of readability (Default: 32)
-min-bytesHow many bytes should be readable as text to approve readability check (Default: 4)
-no-checkDisable the check of readability
# All matches will be replaced
replace "HUH" "OLE" /system/build.prop

# Replace entire line containing text
replace -a "HUH" "OLE" /system/build.prop

# Search and replace in all files in a directory
replace -r "HUH" "OLE" /system

# Only replace if the file as a minimum of 50 readable bytes
replace -bytes 100 -min-bytes 50 "HUH" "OLE" /system/whats_this

# Do multiple replacements
replace "HUH" "OLE" "HAH" "YAH" /system/build.prop
note

Exclusive for text files, so the readability check is important to avoid corrupting binary files or ending the execution abruptly.


remove

Removes text from a file or directory.

ArgumentDescription
TEXTText to remove
PATHFile or directory
-rRecursive (whole directory)
-aRemove entire line containing text
-only-firstJust remove the first coincidence (if used -r this applies to each file, not only the first)
-follow-symlinksFollow Symlinks especially when used -r
-bytesHow many bytes read for the check of readability (Default: 32)
-min-bytesHow many bytes should be readable as text to approve readability check (Default: 4)
-no-checkDisable the check of readability
# All matches will be removed
remove "HUH" /system/build.prop

# Remove entire line containing text
remove -a "HUH" /system/build.prop

# Remove all empty lines
remove -a "" /system/build.prop

# Search and remove in all files in a directory
remove -r "HUH" /system

# Only remove if the file as a minimum of 50 readable bytes
remove -bytes 100 -min-bytes 50 "HUH" /system/whats_this

# Do multiple removals
remove "HUH" "HAH" /system/build.prop
note

Exclusive for text files, so the readability check is important to avoid corrupting binary files or ending the execution abruptly.


replace_name

Renames files/folders matching a pattern.

ArgumentDescription
OLDPattern to match
NEWNew name/pattern
PATHFile or directory
-rRecursive (whole directory)
-fFiles only
-dDirectories only
-regexUse regular expressions
replace_name ".jpg" ".png" /system/test.jpg
replace_name "old" "new" /system/folder_old
replace_name ".bak" "" /system/test.prop.bak
replace_name -r ".jpg" ".png" /system
replace_name -f -r ".bak" "" /system
replace_name -d -r "_ext" "_new" /system
replace_name -regex -r ".bak$" "" /system