Last active
November 13, 2024 22:14
-
-
Save jhauga/4c7aa4602258ba7ef996f5f9e5ca128e to your computer and use it in GitHub Desktop.
Bash script to traverse through a directory, recursing with a call to a function that finds and replaces specific text.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ************************************************************* # | |
# ************************ GITHUB GIST ************************ # | |
# ************************************************************* # | |
# recurse_and_replace.sh | |
# Bash script to traverse through a directory, recursing with a call to a function that finds and replaces specific text. | |
# ########################### | |
# LICENSE # | |
# ******* # | |
# The code in this gist is public domain. # | |
# Licensed as Public Domain CC0 ################################## | |
################################################################## | |
# MAKE EDITS AS NEEDED | |
# ************************************************************* | |
#!/bin/bash | |
# recurse_and_replace | |
# Traverse through a folder or directory using a recursive function to find and replace text. | |
# NOTE - best to call from directory where this script is located. | |
# NOTE - add and/or delete as needed. This is just the base. | |
# See test_recurse_and_replace.sh for a use example. | |
# Start traversing from the directory defined in variable. | |
traverse_directory="." | |
script_filename="$0" | |
# Set a global old and new text variables. | |
_old_text="NAME" | |
_new_text="NEW NAME" | |
# Function to replace strings in files | |
find_text() { | |
# file found and assign to variable | |
local file="$1" | |
# check if the file has any _old_text | |
local count=$(grep -o "$_old_text" "$file" | wc -l) | |
# if file has _old_text | |
if [ "$count" -gt 0 ]; then | |
# replace the contents | |
sed "s|$_old_text|$_new_text|g" "$file" | |
# Get the relative path of the file | |
relative_path=$(realpath --relative-to="$traverse_directory" "$file") | |
# log files changed and count to found_pages.log | |
echo "File: $relative_path" >> found_pages.log | |
echo "Occurrences: $count" >> found_pages.log | |
echo >> found_pages.log | |
fi | |
} | |
# Function that recurses to traverse directories, find old text, replace with new text. | |
traverse_directories() { | |
# using function defined at top of script | |
local dir="$1" | |
# Loop through each file and directory in current folder of directory. | |
for item in "$dir"/*; do | |
if [ -f "$item" ]; then | |
# make sure to exclude this file | |
# not concrete so best to call this script from the directory it is in | |
if [[ "$traverse_directory" = "." && "$item" = "$script_filename" ]]; then | |
echo Probably this file - so skipping replace text function call. | |
else | |
# if file call find_text() | |
find_text "$item" | |
fi | |
elif [ -d "$item" ]; then | |
# if it's a folder recurse | |
traverse_directories "$item" | |
fi | |
done | |
} | |
# Add or clear the log file. | |
if [ -e found_pages.log ]; then | |
# clear log file | |
> found_pages.log | |
else | |
# create a log file | |
touch found_pages.log | |
fi | |
# Finally call the recursing function. | |
traverse_directories "$traverse_directory" | |
# This gist is meant to work as a general idea, guide, or | |
# starting point. Use as needed and/or see fit. | |
# ************************************************************* | |
# ************************************************************* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
************************ SUPPORT FILE ************************ | |
* chmod.txt | |
* Test File - using regular expression to replace special characters. | |
NOTE - in example this is in recurse_and_replace/tldr folder with copied file prefixed "_original-". | |
***************************************** | |
chmod | |
[0mChange the access permissions of a file or directory.More information: https://www.gnu.org/software/coreutils/chmod. | |
- [23;22;24;25;32mGive the [u]ser who owns a file the right to e[x]ecute it: | |
[23;22;24;25;33m chmod u+x {{file}} | |
[0m | |
- [23;22;24;25;32mGive the [u]ser rights to [r]ead and [w]rite to a file/directory: | |
[23;22;24;25;33m chmod u+rw {{file_or_directory}} | |
[0m | |
- [23;22;24;25;32mRemove e[x]ecutable rights from the [g]roup: | |
[23;22;24;25;33m chmod g-x {{file}} | |
[0m | |
- [23;22;24;25;32mGive [a]ll users rights to [r]ead and e[x]ecute: | |
[23;22;24;25;33m chmod a+rx {{file}} | |
[0m | |
- [23;22;24;25;32mGive [o]thers (not in the file owner's group) the same rights as the [g]roup: | |
[23;22;24;25;33m chmod o=g {{file}} | |
[0m | |
- [23;22;24;25;32mRemove all rights from [o]thers: | |
[23;22;24;25;33m chmod o= {{file}} | |
[0m | |
- [23;22;24;25;32mChange permissions recursively giving [g]roup and [o]thers the ability to [w]rite: | |
[23;22;24;25;33m chmod -R g+w,o+w {{directory}} | |
[0m | |
- [23;22;24;25;32mRecursively give [a]ll users [r]ead permissions to files and e[X]ecute permissions to sub-directories within a directory: | |
[23;22;24;25;33m chmod -R a+rX {{directory}} | |
[0m[0m | |
* This file is support for this gist and is meant to serve as a | |
* test, way of implementation, or an additional explanation for | |
* the main gist file. | |
**************************************************************** | |
**************************************************************** |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
************************ SUPPORT FILE ************************ | |
* lecture.txt | |
* Test File - for specifying specific text to be replaced. | |
NOTE - in example this is in recurse_and_replace root folder with copied file prefixed "_original-". | |
Alright, class, let's delve into the vast world of computer science, shall we? This field is as diverse | |
as it is fascinating, touching on everything from the theory behind how computers work to the practical | |
applications through programming languages. | |
### Introduction to Computer Science: | |
**Computer science** is the study of computers and computational systems. It involves understanding how | |
computers function, how data is processed and stored, and how to develop software to solve real-world problems. | |
### Programming Languages: | |
Now, programming languages are the tools we use to communicate with computers. Here are a few: | |
1. **Python**: Known for its simplicity and readability, Python is great for beginners. It’s used in web | |
development, data analysis, artificial intelligence (AI), and scientific computing. For example, you can | |
write a simple program to print "Hello, World!" like this: | |
```python | |
print("Hello, World!") | |
``` | |
2. **Java**: It's used in developing Android apps, enterprise-level applications, and large systems. Here's a | |
basic Java program that prints the same message: | |
```java | |
public class HelloWorld { | |
public static void main(String[] args) { | |
System.out.println("Hello, World!"); | |
} | |
} | |
``` | |
3. **JavaScript**: Primarily used for web development, JavaScript adds interactivity to websites. You can | |
create pop-ups or modify webpage content dynamically. Here's a simple script that displays an alert: | |
```javascript | |
alert("Hello, World!"); | |
``` | |
4. **C++**: This language is used for systems/software development, gaming, and high-performance applications. | |
It’s known for its speed and performance. Here’s an example printing "Hello, World!" in C++: | |
```cpp | |
#include <iostream> | |
using namespace std; | |
int main() { | |
cout << "Hello, World!" << endl; | |
return 0; | |
} | |
``` | |
### Applications in Computer Science: | |
In computer science, these languages and many others are tools we use to create software that solves problems. | |
For instance: | |
- **Web Development**: JavaScript, HTML, and CSS are used to create interactive and visually appealing websites. | |
- **Data Analysis**: Python with libraries like Pandas and NumPy helps process and analyze large sets of data. | |
- **Mobile App Development**: Java and Kotlin for Android, Swift for iOS, enable us to build mobile applications. | |
### Conclusion: | |
This introductory glimpse into computer science barely scratches the surface. It's a vast field with countless | |
possibilities and applications. As you progress, you’ll explore algorithms, data structures, cybersecurity, | |
artificial intelligence, and so much more. So, buckle up and get ready for an exciting journey through the | |
world of computers and technology! | |
* This file is support for this gist and is meant to serve as a | |
* test, way of implementation, or an additional explanation for | |
* the main gist file. | |
**************************************************************** | |
**************************************************************** |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
************************ SUPPORT FILE ************************ | |
* recurse_and_replace.log | |
* The log file that documents relative path and number of occurances. | |
File: lecture.txt | |
Occurrences of Computer Science:: 2 | |
File: man/tldr.txt | |
Occurrences of NAME: 1 | |
File: musical.txt | |
Occurrences of Title: "New York, New York": 1 | |
File: recurse_and_replace.log | |
Occurrences of Computer Science:: 1 | |
File: tldr/chmod.txt | |
Occurrences of Regular Expression: 0 | |
* This file is support for this gist and is meant to serve as a | |
* test, way of implementation, or an additional explanation for | |
* the main gist file. | |
**************************************************************** | |
**************************************************************** |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
************************ SUPPORT FILE ************************ | |
* test_recurse_and_replace.log | |
* Condensed terminal output from the test file test_recurse_and_replace.sh | |
1 -------------------------- | |
NOTE - in example this is in recurse_and_replace root folder with copied file prefixed "_original-". | |
Alright, class, let's delve into the vast world of computer science, shall we? This field is as diverse | |
as it is fascinating, touching on everything from the theory behind how computers work to the practical | |
applications through programming languages. | |
### Introduction to Computer Science - LECURE I SUMMER SEMESTER | |
**Computer science** is the study of computers and computational systems. It involves understanding how | |
computers function, how data is processed and stored, and how to develop software to solve real-world problems. | |
### Programming Languages: | |
Now, programming languages are the tools we use to communicate with computers. Here are a few: | |
2 -------------------------- | |
NOTE - in example this is in recurse_and_replace/man folder with copied file prefixed "_original-". | |
***************************************** | |
TLDR(1) User Commands TLDR(1) | |
NEW CHANGED NAME - it worked | |
tldr - manual page for tldr 0.4.0.1 | |
SYNOPSIS | |
tldr [-v|--version] [--update] COMMAND | |
DESCRIPTION | |
tldr - Simplified and community-driven man pages | |
tldr Client program | |
3 -------------------------- | |
NOTE - in example this is in recurse_and_replace root folder with copied file prefixed "_original-". | |
### Title: "Echos of New York" | |
#### Act 1: Small Town Dreams and City Life | |
**Scene 1: The Departure** | |
*Setting: A small town in the late 1940s. Family and friends are gathered at the train station to bid farewell to the young man.* | |
**Song: "New York, New York"** | |
**Young Man**: (to his family) "I know it's a big step, but New York is where dreams come true. I've got to take my shot." | |
**Family Member**: "We'll miss you, but we believe in you. Go make us proud." | |
1 -------------------------- | |
File: lecture.txt | |
Occurrences of Computer Science - LECURE I SUMMER SEMESTER: 2 | |
File: man/tldr.txt | |
Occurrences of NAME: 1 | |
File: musical.txt | |
Occurrences of Title: "New York, New York": 1 | |
1 -------------------------- | |
4 -------------------------- | |
NOTE - in example this is in recurse_and_replace/tldr folder with copied file prefixed "_original-". | |
***************************************** | |
chmod | |
Change the access permissions of a file or directory.More information: https://www.gnu.org/software/coreutils/chmod. | |
Give the [u]ser who owns a file the right to e[x]ecute it: | |
chmod u+x {{file}} | |
Give the [u]ser rights to [r]ead and [w]rite to a file/directory: | |
chmod u+rw {{file_or_directory}} | |
Remove e[x]ecutable rights from the [g]roup: | |
chmod g-x {{file}} | |
Give [a]ll users rights to [r]ead and e[x]ecute: | |
* This file is support for this gist and is meant to serve as a | |
* test, way of implementation, or an additional explanation for | |
* the main gist file. | |
**************************************************************** | |
**************************************************************** |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
************************ SUPPORT FILE ************************ | |
* test_recurse_and_replace.sh | |
* An example of running recurse_and_replace.sh where additional conditions and variables were added in order to display different use cases. | |
#!/bin/bash | |
# test_recurse_and_replace | |
# Traverse through a folder or directory using a recursive function to find and replace text. | |
# NOTE - best to call from directory where this script is located. | |
# NOTE - example has extra conditions and variables commented above -> *-FOR-EXAMPLE-* | |
# Start traversing from the directory defined in variable. | |
traverse_directory="recurse_and_replace" | |
script_filename="$0" | |
# *-FOR-EXAMPLE-* | |
skip_files="_original" | |
# Set a global uri variables with old and new uri | |
_old_text="per CONDITION" | |
_new_text="CHANGED per condition" | |
# Function to replace strings in files | |
find_text() { | |
# file found and assign to variable | |
local file="$1" | |
local folder="$2" | |
# *-FOR-EXAMPLE-* | |
local reg_ex_it=0 | |
if [ -e "$folder" ]; then | |
folder="normal_run" | |
else | |
# *-FOR-EXAMPLE-* [1], [2], [3], and [4] | |
if [ "$folder" = "man" ]; then | |
# [2] | |
echo && echo 2 -------------------------- && echo | |
_old_text="NAME" | |
_new_text="NEW CHANGED NAME - it worked" | |
elif [ "$folder" = "tldr" ]; then | |
# [4] | |
echo && echo 4 -------------------------- && echo | |
_old_text="Regular Expression" | |
_new_text="" | |
reg_ex_it=1 | |
else | |
# [1] and [3] $folder = "normal_run" | |
if [ "$(echo $file | sed "s|.*/||" )" = "musical.txt" ]; then | |
# [3] | |
echo && echo 3 -------------------------- && echo | |
_old_text="Title: \"New York, New York\"" | |
_new_text="Title: \"Echos of New York\"" | |
else | |
# [1] | |
echo && echo 1 -------------------------- && echo | |
_old_text="Computer Science:" | |
_new_text="Computer Science - LECURE I SUMMER SEMESTER" | |
fi | |
fi | |
fi | |
# check if the file has any _old_text | |
local count=$(grep -o "$_old_text" "$file" | wc -l) | |
# if file has _old_text | |
if [[ "$count" -gt 0 || $reg_ex_it = 1 ]]; then | |
# *-FOR-EXAMPLE-* | |
if [ $reg_ex_it = 1 ]; then | |
sed -E "s|^(.*)([0-9;]+)m||g" "$file" | head -n 15 | |
else | |
# replace the contents | |
sed "s|$_old_text|$_new_text|g" "$file" | head -n 15 | |
fi | |
# Get the relative path of the file | |
relative_path=$(realpath --relative-to="$traverse_directory" "$file") | |
# log files changed and count to found_pages.log | |
echo "File: $relative_path" >> $traverse_directory/recurse_and_replace.log | |
# *-FOR-EXAMPLE-* | |
echo "Occurrences of $_old_text: $count" >> $traverse_directory/recurse_and_replace.log | |
echo >> $traverse_directory/recurse_and_replace.log | |
fi | |
} | |
# Function that recurses to traverse directories, find old text, replace with new text. | |
traverse_directories() { | |
# using function defined at top of script | |
local dir="$1" | |
# Loop through each file and directory in current folder of directory. | |
for item in "$dir"/*; do | |
if [ -f "$item" ]; then | |
# make sure to exclude this file | |
# not concrete so best to call this script from the directory it is in | |
if [[ "$traverse_directory" = "." && "$item" = "$script_filename" ]]; then | |
echo Probably this file - so skipping replace text function call. | |
else | |
# skip prefixed file | |
# *-FOR-EXAMPLE-* | |
check_if_skip_file=$(echo $item | sed -e "s|$dir/||" -e s/.txt// -e s/-.*//) | |
if [ ! "$check_if_skip_file" = "$skip_files" ]; then | |
# *-FOR-EXAMPLE-* [1 [a][b]], [2], amd [3] | |
if [ "$dir" = "$traverse_directory/man" ]; then | |
# [2] | |
# if file call find_text() | |
find_text "$item" "man" && echo | |
elif [ "$dir" = "$traverse_directory/tldr" ]; then | |
# [4] | |
find_text "$item" "tldr" && echo | |
else | |
# [1] and [3] | |
find_text "$item" && echo | |
fi | |
fi | |
fi | |
elif [ -d "$item" ]; then | |
# if it's a folder recurse | |
traverse_directories "$item" | |
fi | |
done | |
} | |
# Add or clear the log file. | |
if [ -e found_pages.log ]; then | |
# clear log file | |
> $traverse_directory/recurse_and_replace.log | |
else | |
# create a log file | |
touch $traverse_directory/recurse_and_replace.log | |
fi | |
# Finally call the recursing function. | |
traverse_directories "$traverse_directory" | |
* This file is support for this gist and is meant to serve as a | |
* test, way of implementation, or an additional explanation for | |
* the main gist file. | |
**************************************************************** | |
**************************************************************** |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
************************ SUPPORT FILE ************************ | |
* tldr.txt | |
* Test File - for specifying specific text to be replaced. | |
NOTE - in example this is in recurse_and_replace/man folder with copied file prefixed "_original-". | |
***************************************** | |
TLDR(1) User Commands TLDR(1) | |
NAME | |
tldr - manual page for tldr 0.4.0.1 | |
SYNOPSIS | |
tldr [-v|--version] [--update] COMMAND | |
DESCRIPTION | |
tldr - Simplified and community-driven man pages | |
tldr Client program | |
Available options: | |
-h,--help | |
Show this help text | |
-v,--version | |
Show version | |
--update | |
Update tldr pages | |
COMMAND | |
name of the command | |
tldr 0.4.0.1 February 2020 TLDR(1) | |
* This file is support for this gist and is meant to serve as a | |
* test, way of implementation, or an additional explanation for | |
* the main gist file. | |
**************************************************************** | |
**************************************************************** |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment