|
Download Multi Document Block Oriented Search and Replace script. Web Masters, and Programmers are you in need of a way to make large changes to all of your pages or a selection of files all at once? This GUI enabled script does search and replace of large block elements across as many files as you select for it to work on. I had been in need of a tool to do large block element search and replace for quite some time to help me administer my web sites. Sometimes there are changes I want to make to all of the pages on my site at once, and I could not find an editor that would accomplish the feat of large block search and replace. This script depends on the Xdialog package for the GUI widgets it uses to interact with it's users. To install Xdialog issue the following command in Terminal. sudo apt-get install xdialog To use the script, simply decompress it from the MultiDocBlockSearchReplace.sh.zip file into any folder in your home folder. You can then add the following command to a menu entry to start it, or you can issue the command from Terminal as well. /home/username/folder/path/MultiDocBlockSearchReplace.sh Replace "username", "folder", and "path" with the actual folder path as it exists on your computer. Here is the source code for the MultiDocBlockSearchReplace.sh script file.
#!/usr/bin/env bash
#
# This script is a GUI enabled, multi-document, block oriented search, and replace program.
#
# this function does the actual replacement of one block with another
function DoReplace {
# Four arguments are passed in, FileContents, SearchString, ReplaceString, and ReplaceAll
FileContent="$1"
SearchString="$2"
ReplaceString="$3"
ReplaceAll="$4"
if [ "$ReplaceAll" == "True" ]
then
# Do the actual replacement of all occurrences of SearchString with ReplaceString.
FileContent=${FileContent//"$SearchString"/"$ReplaceString"}
else
# Replace only the first occurrence of SearchString with ReplaceString.
FileContent=${FileContent/"$SearchString"/"$ReplaceString"}
fi
# Return the new value of FileContent variable to the calling assignment.
echo "$FileContent"
}
# This function allows choosing, or typing in a file extension to work with.
function SelectFileType {
# Present user with a drop down list of possible file types, and allow typing in a different one as well.
FileType=`Xdialog --auto-placement --stdout --title "MDBOSR - Select File Type" --editable --combobox "Select a file type from the drop down list, or type one into the list." 0 0 "html" "htm" "css" "sh" "txt" "js"`
# test for Cancel, or X button click.
ReturnValue=$?
case $ReturnValue in
1) # Cancel clicked, do nothing, and return to the menu
return;;
255) # X button clicked, do nothing, and return to the menu
return;;
esac
# return value of FileType to calling assignment statement.
echo "$FileType"
}
# This function inventories the specified folder for files of FileType as passed in.
function MakeFileList {
# Load variables with passed in values
Directory=$1
cd $Directory
FileType=$2
Recursive=$3 # True or False, whether or not to search subfolders for files of FileType
if [ "$Recursive" != "True" ]
then
ls -x -1 *.$FileType > "$DirectoryName/FileList.txt"
FileList=""
# loop through FileList.txt adding the path to the front of each filename.
while read EachFile; do
ThisPathandName="$Directory$EachFile"
ThisPathandName=${ThisPathandName// /%20}
# Force a line feed in the file list.
FileList="$FileList
$ThisPathandName"
done < "$DirectoryName/FileList.txt"
else
FileList=`find -type f -name \*.$FileType`
# URL encode the filenames so they work with the comboboxes.
FileList=${FileList// /%20}
# Get rid of ./ at front of filename and path.
FileList=${FileList//.\//$Directory\/}
fi
# Return value of FileList to calling assignment statement.
echo "$FileList"
}
# This function allows the user to specify the folder he wishes to work in.
function SelectFolder {
# Prompt user to select a folder to work in.
SelectedFolder=`Xdialog --auto-placement --stdout --title "MDBOSR - Select Working Folder" --no-buttons --dselect "$DirectoryName" 0 0`
echo "$SelectedFolder"
}
# This function allows the user to select the files they want changes applied to from a checklist
function SelectFiles {
# Assign passed in values to local variables
FileList="$1"
# Clean up old file.
rm -f "$DirectoryName/FileList.txt"
# Write FileList to a temporary file.
echo "$FileList" > $DirectoryName/FileList.txt
# Generate an array of values to pass to the check list widget.
LoopCount=0
ArgumentCount=1
# Loop through the file, adding values to the argument array
while read EachFile; do
# Write $EachFile to tag argument position in array
Arguments[$ArgumentCount]="$EachFile"
ArgumentCount=$(( $ArgumentCount + 1 ))
# Write value of LoopCount to the item argument position in the Arguments array.
Arguments[$ArgumentCount]=$LoopCount
ArgumentCount=$(( $ArgumentCount + 1 ))
# Write "off" to the Status arguments array position.
Arguments[$ArgumentCount]="off"
ArgumentCount=$(( $ArgumentCount + 1 ))
LoopCount=$(( $LoopCount + 1 ))
done < "$DirectoryName/FileList.txt"
# Present user with a check list of files to select from.
SelectedFiles=`Xdialog --auto-placement --stdout --separator "\n" --title "MDBOSR - Select Working Files" --checklist "Select all of the files you want to broadcast changes through." 20 80 16 "${Arguments[@]}"`
echo "$SelectedFiles"
}
# This function allows the user to specify the Search Term to be replaced by Replace Term.
function DefineSearchTerm {
# Assign passed in values to local variables.
FileList="$1"
# Prompt user to select a file to copy Search Term from.
SelectedFile=`Xdialog --auto-placement --stdout --title "MDBOSR - Select File" --combobox "Select a file to copy Search Term from." 0 0 $FileList`
# test for Cancel, or X button click.
ReturnValue=$?
case $ReturnValue in
1) # Cancel clicked, do nothing, and exit function.
return;;
255) # X button clicked, do nothing, and exit function.
return;;
esac
# Remove the URL encoding from $SelectedFile so we can open the actual file.
SelectedFile=${SelectedFile//%20/ }
# pop up the selected file in a text box, so the user can copy text from it.
Xdialog --auto-placement --title "MDBOSR - Copy Search Term" --textbox "$SelectedFile" 30 80 &
touch "$DirectoryName/dummy.txt"
SearchTerm=`Xdialog --auto-placement --stdout --title "MDBOSR - Paste Search Term" --editbox "$DirectoryName/dummy.txt" 30 80`
rm -f "$DirectoryName/dummy.txt"
echo "$SearchTerm"
}
# This function allows the user to specify the Replace Term to replace Search Term.
function DefineReplaceTerm {
# Assign passed in values to local variables.
FileList="$1"
# Prompt user to select a file to copy Replace Term from.
SelectedFile=`Xdialog --auto-placement --stdout --title "MDBOSR - Select File" --combobox "Select a file to copy Replace Term from." 0 0 $FileList`
# test for Cancel, or X button click.
ReturnValue=$?
case $ReturnValue in
1) # Cancel clicked, do nothing, and exit function.
return;;
255) # X button clicked, do nothing, and exit function.
return;;
esac
# Remove the URL encoding from $SelectedFile so we can open the actual file.
SelectedFile=${SelectedFile//%20/ }
# pop up the selected file in a text box, so the user can copy text from it.
Xdialog --auto-placement --title "MDBOSR - Copy Replace Term" --textbox "$SelectedFile" 30 80 &
touch "$DirectoryName/dummy.txt"
ReplaceTerm=`Xdialog --auto-placement --stdout --title "MDBOSR - Paste Replace Term" --editbox "$DirectoryName/dummy.txt" 30 80`
rm -f "$DirectoryName/dummy.txt"
echo "$ReplaceTerm"
}
# Main program starts here.
# Initialize the directory name of the current working folder as a global variable.
DirectoryName=`dirname $0`
# Start the Main Menu loop.
while [ "$MenuChoice" != "Exit" ]; do
# Pop up the menu.
MenuChoice=`Xdialog --auto-placement --stdout --title "Multi Document Block Oriented Search Replace" --no-tags --menubox "Please make a selection below." 20 60 16 "FileType" "Select type of files to work on" "Folder" "Select Working Folder" "SetRecursive" "Set Folder Search to Recursive." "SetNoRecurse" "Set Folder Search to Non Recursive" "SelectFiles" "Select Files to Make Changes to" "SetSearch" "Set Search Term" "SetReplace" "Set Replace Term" "Replace" "Replace Single Occurrence of Search Term in All Files" "ReplaceAll" "Replace All Occurrences of Search Term in All Files" "Exit" "Exit this program."`
# test for Cancel, or X button click.
ReturnValue=$?
case $ReturnValue in
1) # Cancel clicked, do nothing, and exit program
exit;;
255) # X button clicked, do nothing, and exit program.
exit;;
esac
# Test Menu Choice, and branch accordingly.
case $MenuChoice in
"FileType")
FileType=`SelectFileType`;;
"Folder")
Folder=`SelectFolder`;;
"SetRecursive")
Recursive="True";;
"SetNoRecurse")
Recursive="False";;
"SelectFiles")
FileList=`MakeFileList $Folder $FileType $Recursive`
FileList=`SelectFiles "$FileList"`;;
"SetSearch")
SearchTerm=`DefineSearchTerm "$FileList"`;;
"SetReplace")
ReplaceTerm=`DefineReplaceTerm "$FileList"`;;
"Replace")
echo "$FileList" > "$DirectoryName/FileList.txt"
while read ThisFile; do
ThisFile=${ThisFile//%20/ }
FileContents=`cat "$ThisFile"`
FileContents=`DoReplace "$FileContents" "$SearchTerm" "$ReplaceTerm" "False"`
echo "$FileContents" > "$ThisFile"
done < "$DirectoryName/FileList.txt";;
"ReplaceAll")
echo "$FileList" > "$DirectoryName/FileList.txt"
while read ThisFile; do
ThisFile=${ThisFile//%20/ }
FileContents=`cat "$ThisFile"`
FileContents=`DoReplace "$FileContents" "$SearchTerm" "$ReplaceTerm" "True"`
echo "$FileContents" > "$ThisFile"
done < "$DirectoryName/FileList.txt" ;;
"Exit")
rm -f "$DirectoryName/FileList.txt"
exit;;
esac
done
Download Multi Document Block Oriented Search and Replace script. To use the program you need to do several things in a certain order to set up the file set you want to work on. Here is a screen shot of the main menu of Multi Document Block Oriented Search Replace. ![]() ![]() The first thing you need to do is set the type of files you would like to work on, so select the first menu item "Select type of files to work on", and click OK. You will be presented with a drop down list of many popular file types. The drop down list is editable, so if the file extension you want to work on is not in the list, simply click in the box, and type in the extension of the type of files you would like to work on. ![]() Next you will need to set the working folder. This is the folder where the files you want to work on reside. There are two settings for searching for files you want to work on. One setting is recursive, which means to search sub folders of the working folder for files as well as searching the working folder for files. The other setting is non recursive which means to only search the set working folder for files to work on. There are two menu entries for changing this setting. To set the working folder select the menu entry "Select Working Folder". You will get the dialog shown at the right. Navigate your way to the folder that contains the files you want to work on, and click OK on the folder selection dialog. ![]() Once you have all of those settings made it is time to "Select Files to Make Changes to". This menu entry selection presents you with a check list of all of the files found that match the type settings extension. Click each file that you want to add to the working set in the list, then click OK. ![]() Now it is time to define the block of text you would like to search for and replace. Select "Set Search Term" from the main menu, and click OK. You will be presented with a drop down list of the files in your working set to select a file to copy a search term from. After selecting a file, you will be presented with two dialogs, one with the file you selected in it, and the other to paste the search term into. Use your mouse, or the keyboard to select a block of text in the dialog with the file you selected in it. You will have to press CTRL-C to copy the block of text you selected, as Xdialog widgets do not support context menus for your mouse. Now paste the copied text into the paste search term dialog with either CTRL-V, or by clicking your mouse's scroll wheel. The same procedure applies to the menu entry "Set Replace Term", with it allowing you to select a file to copy the replace term from, then presenting you with the file to copy from, and a dialog to paste the replace term into. ![]() ![]() Now you need to select the appropriate menu entry from the two "Replace Single Occurrence of Search Term in All Files", and "Replace All Occurrences of Search Term in All Files". Either of these menu entries will begin the actual process of doing the search and replace operation across all of the files you have selected for a working set. Have some patience as the menu disappears, and the script works on replacing the search term in all of the files with the replace term, as it can take a long time for this operation to complete. One it is done, the main menu will appear again, and you will know that the operation is complete. You may make changes to as many files as you select for the working set. You can select as few as one file to work on, or as many as you think this script can handle. I've successfully made changes to around 60 files at once with it, which took around five minutes to complete with a large block of text being searched for and replaced. That's a lot faster than the hours it used to take me to make a change of this magnitude. I have no way to test it for a larger file set than that, as I do not have a convenient large set of files for the script to work on other than the web pages for my web sites, so I have no idea what the limits are as far as how many files can be worked on at once. If you find a situation where you have selected more files than the script will handle please email me, and let me know how many files you tried when it failed, and how large the files were. I hereby release MultiDocBlockSearchReplace.sh as open source software for Linux computers. I have thoroughly tested it under Ubuntu 8.04 Hardy Heron, and have no idea if it will work on other Linux distributions. Give it a try, and let me know if it works in your flavor of Linux. Download Multi Document Block Oriented Search and Replace script. Help me keep writing code for others to use. Please consider making a donation of whatever you can afford if you use my scripts, even something as small as one dime would help a lot. Thanks. |
|
| Last modified on: |