✏️ Editing Files Tools
Utilities for editing files.
savestate
Records a file’s current state into a variable.
Argument | Description |
---|---|
VAR | Variable to store state |
FILE | File 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.
Argument | Description |
---|---|
LINE | Pattern to find line |
PROP | Property to find |
NEW | New property value |
FILE | Fstab file |
# Replace fileencryption=ice with encryptable in userdata line
patch_fstab userdata "fileencryption" "encryptable" "/vendor/etc/fstab.qcom"
update_file
Updates existing prop lines in a file.
Argument | Description |
---|---|
SRC | File with new props |
DEST | Destination file |
-force | If 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.
Argument | Description |
---|---|
LINE | Line(s) to update |
FILE | Destination file |
-force | If 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.
Argument | Description |
---|---|
-open START END | Start and end tags of XML section (multiple allowed) |
-in PATTERN | Pattern to filter section |
-change-value ATTR VAL | Change attribute value (ATTR="VAL" ) |
-change-tag TAG VAL | Change value between tags (<TAG> VAL </TAG> ) |
-change-content OLD NEW | Replace text in section |
-add TEXT | Add text after section |
-add-inside TEXT | Add text inside section |
-after-line LINE TEXT | Add text after line |
-before-line LINE TEXT | Add text before line |
-get-value | Returns the current content of the section without including opening and closing tags. |
-remove | Removes the entire current section of the last -open done |
-print | Print full result instead of editing |
-print-result | Similar to -print but only prints the modified -open sections without merging them into the rest of the structure. |
-no-auto-spaces | Disable auto-spacing |
FILE | XML 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
It supports tags with attributes that span multiple lines, which is common for readability. However, these line breaks are not guaranteed to be preserved.
-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
Adds lines from multiple files to a destination file.
Argument | Description |
---|---|
-after-line LINE | Add after this line (multiple allowed) |
-before-line LINE | Add before this line (multiple allowed) |
SRC | Source file(s) |
DEST | Destination 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.
Argument | Description |
---|---|
-after-line LINE | Add after this line (multiple allowed) |
-before-line LINE | Add before this line (multiple allowed) |
LINE | Line(s) to add |
DEST | Destination 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.
Argument | Description |
---|---|
OLD | Text to replace |
NEW | Replacement text |
PATH | File or directory |
-r | Recursive (whole directory) |
-a | Replace entire line containing text |
-only-first | Just replace the first coincidence (if used -r this applies to each file, not only the first) |
-follow-symlinks | Follow Symlinks especially when used -r |
-bytes | How many bytes read for the check of readability (Default: 32 ) |
-min-bytes | How many bytes should be readable as text to approve readability check (Default: 4 ) |
-no-check | Disable 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
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.
Argument | Description |
---|---|
TEXT | Text to remove |
PATH | File or directory |
-r | Recursive (whole directory) |
-a | Remove entire line containing text |
-only-first | Just remove the first coincidence (if used -r this applies to each file, not only the first) |
-follow-symlinks | Follow Symlinks especially when used -r |
-bytes | How many bytes read for the check of readability (Default: 32 ) |
-min-bytes | How many bytes should be readable as text to approve readability check (Default: 4 ) |
-no-check | Disable 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
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.
Argument | Description |
---|---|
OLD | Pattern to match |
NEW | New name/pattern |
PATH | File or directory |
-r | Recursive (whole directory) |
-f | Files only |
-d | Directories only |
-regex | Use 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