Skip to content

Instantly share code, notes, and snippets.

@jhauga
Last active November 13, 2024 22:14
Show Gist options
  • Save jhauga/4c7aa4602258ba7ef996f5f9e5ca128e to your computer and use it in GitHub Desktop.
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.
# ************************************************************* #
# ************************ 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.
# *************************************************************
# *************************************************************
************************ 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.
****************************************************************
****************************************************************
************************ 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.
****************************************************************
****************************************************************
************************ 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.
****************************************************************
****************************************************************
************************ 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.
****************************************************************
****************************************************************
************************ 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.
****************************************************************
****************************************************************
************************ 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