initial
This commit is contained in:
commit
74ae93a96e
4 changed files with 94691 additions and 0 deletions
156
joplin notion extension/linux/Snippets/Bidirectional sync.md
Normal file
156
joplin notion extension/linux/Snippets/Bidirectional sync.md
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
Bidirectional sync
|
||||
https://sentrytwo.com/6bb78a2539
|
||||
|
||||
sync_directories1.sh
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
# SOURCE="/home/hpes/Videos/impnew/notes/keepaas_offline"
|
||||
# DESTINATION=" /home/hpes/Dropbox_keepaas/Apps/Keepaas2Android"
|
||||
|
||||
SOURCE=$1
|
||||
DESTINATION=$2
|
||||
|
||||
db_name= "main.kdbx"
|
||||
|
||||
SOURCE_FILE="$SOURCE/${db_name}"
|
||||
DESTINATION_FILE= "$DESTINATION/${db_name}"
|
||||
|
||||
# Function to sync directories
|
||||
sync_directories() {
|
||||
# rsync -avu --ignore-existing "$SOURCE/${db_name}" "$DESTINATION/${db_name}"
|
||||
rsync -avu "$SOURCE/${db_name}" "$DESTINATION/${db_name}"
|
||||
}
|
||||
|
||||
|
||||
# Ensure initial sync
|
||||
sync_directories
|
||||
|
||||
|
||||
|
||||
# Monitor the source directory for any activity, and sync upon changes
|
||||
inotifywait -mre close_write,create,delete,move "$SOURCE" |
|
||||
while read -r directory events filename; do
|
||||
sync_directories
|
||||
done
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
sync_directories.sh
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
# SOURCE="/home/hpes/Videos/impnew/notes/keepaas_offline"
|
||||
# DESTINATION=" /home/hpes/Dropbox_keepaas/Apps/Keepaas2Android"
|
||||
|
||||
SOURCE=$1
|
||||
DESTINATION=$2
|
||||
|
||||
db_name= "main.kdbx"
|
||||
|
||||
SOURCE_FILE="$SOURCE/${db_name}"
|
||||
DESTINATION_FILE= "$DESTINATION/${db_name}"
|
||||
|
||||
# Function to sync directories
|
||||
sync_directories2() {
|
||||
rsync -avu "$DESTINATION/${db_name}" "$SOURCE/${db_name}"
|
||||
}
|
||||
|
||||
# Ensure initial sync
|
||||
sync_directories2
|
||||
|
||||
|
||||
|
||||
# Monitor the source directory for any activity, and sync upon changes
|
||||
inotifywait -mre close_write,create,delete,move "$SOURCE" |
|
||||
while read -r directory events filename; do
|
||||
sync_directories2
|
||||
done
|
||||
|
||||
|
||||
|
||||
```
|
||||
sync1.sh
|
||||
```bash
|
||||
/home/hpes/Videos/imp/scripts/sync_directories/sync_directories1.sh /home/hpes/Videos/impnew/notes/keepaas_offline /home/hpes/Dropbox_keepaas/Apps/Keepaas2Android
|
||||
|
||||
```
|
||||
|
||||
sync2.sh
|
||||
```bash
|
||||
/home/hpes/Videos/imp/scripts/sync_directories/sync_directories2.sh /home/hpes/Videos/impnew/notes/keepaas_offline /home/hpes/Dropbox_keepaas/Apps/Keepaas2Android
|
||||
|
||||
```
|
||||
|
||||
|
||||
sync_bi.sh
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
SCREEN_NAME1="sync1"
|
||||
SCREEN_NAME1_SCRIPT_PATH="/home/hpes/Videos/imp/scripts/sync_directories/sync1.sh"
|
||||
SCREEN_NAME2="sync2"
|
||||
SCREEN_NAME2_SCRIPT_PATH="/home/hpes/Videos/imp/scripts/sync_directories/sync2.sh"
|
||||
|
||||
start_script() {
|
||||
# Check if the screen session already exists
|
||||
if screen -list | grep -q "$SCREEN_NAME1"; then
|
||||
echo "Session already exists. Please stop it first or choose another name."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Start the screen session detached mode
|
||||
screen -dmS $SCREEN_NAME1 "$SCREEN_NAME1_SCRIPT_PATH"
|
||||
screen -dmS $SCREEN_NAME2 "$SCREEN_NAME2_SCRIPT_PATH"
|
||||
|
||||
echo "Script started in background under screen session '$SCREEN_NAME1' and '$SCREEN_NAME2'."
|
||||
}
|
||||
|
||||
stop_script() {
|
||||
# Kill the screen session
|
||||
screen -S $SCREEN_NAME1 -X quit
|
||||
screen -S $SCREEN_NAME2 -X quit
|
||||
echo "Screen session '$SCREEN_NAME1' and '$SCREEN_NAME2' stopped."
|
||||
}
|
||||
|
||||
# Check argument passed
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 {start|stop}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
start_script
|
||||
;;
|
||||
stop)
|
||||
stop_script
|
||||
;;
|
||||
*)
|
||||
echo "Invalid option: $1"
|
||||
echo "Usage: $0 {start|stop}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# screen -dmS sync1 ./sync1.sh
|
||||
# screen -dmS sync2 ./sync2.sh
|
||||
|
||||
|
||||
```
|
||||
|
||||
Finally in `.bashrc` add
|
||||
```bash
|
||||
# creating alias for starting sync
|
||||
alias startsync="/home/hpes/Videos/imp/scripts/sync_directories/screen/sync_bi.sh start"
|
||||
|
||||
# run command for starting sync
|
||||
startsync
|
||||
|
||||
# creating alias for stopping sync
|
||||
alias closesync="/home/hpes/Videos/imp/scripts/sync_directories/screen/sync_bi.sh stop"
|
||||
```
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
deleting every 10th file
|
||||
|
||||
```sh
|
||||
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Directory containing save files (defaults to current directory)
|
||||
DIR="${1:-.}"
|
||||
|
||||
# Set to 1 to actually delete files; otherwise, preview only
|
||||
DELETE=0
|
||||
|
||||
mapfile -t files < <(
|
||||
find "$DIR" -maxdepth 1 -type f \
|
||||
-name 'ManualSave_*.sav' \
|
||||
-printf '%T@ %p\n' |
|
||||
sort -n |
|
||||
cut -d' ' -f2-
|
||||
)
|
||||
|
||||
total=${#files[@]}
|
||||
|
||||
echo "Found $total save files."
|
||||
echo "Keeping every 10th file, ordered oldest to newest."
|
||||
echo
|
||||
|
||||
for ((i = 0; i < total; i++)); do
|
||||
if (( (i + 1) % 10 == 0 )); then
|
||||
echo "KEEP ${files[i]}"
|
||||
else
|
||||
if (( DELETE )); then
|
||||
rm -- "${files[i]}"
|
||||
echo "DELETE ${files[i]}"
|
||||
else
|
||||
echo "WOULD DELETE ${files[i]}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
if (( DELETE )); then
|
||||
echo "Done."
|
||||
else
|
||||
echo "Dry run only. No files were deleted."
|
||||
echo "To enable deletion, change DELETE=0 to DELETE=1."
|
||||
fi
|
||||
|
||||
```
|
||||
|
|
@ -0,0 +1,243 @@
|
|||
export file metadata and view it in nice frontend
|
||||
|
||||
**from llm**
|
||||
|
||||
It sounds like you're looking to create a **file explorer with metadata** and **tree view** functionality. Here's a general approach on how you can achieve this, even if you don't have direct access to the files themselves:
|
||||
|
||||
### Steps to Create a File Explorer with Metadata and Tree View
|
||||
|
||||
1. **Get the Directory Structure:**
|
||||
You can use a **recursive function** to traverse the directory and collect information about files and folders in a hierarchical structure (like a tree view). The key is to capture all relevant metadata along with each file and folder.
|
||||
|
||||
2. **Collect Metadata:**
|
||||
For each file and folder, you can collect the following metadata:
|
||||
|
||||
* **File name**
|
||||
* **File size**
|
||||
* **File type/extension**
|
||||
* **Creation date**
|
||||
* **Last modified date**
|
||||
* **Permissions** (Read/Write/Execute)
|
||||
* **Owner (if available)**
|
||||
|
||||
3. **Export the Data:**
|
||||
Once you've gathered all this information, you can export it to a structured format such as **JSON** or **CSV**. JSON would be ideal for this, as it can represent hierarchical data.
|
||||
|
||||
4. **Display with Tree View:**
|
||||
You can then build a tree view UI using HTML, JavaScript, and CSS (e.g., using frameworks like **React** or **Vue.js**). Each item in the tree can be toggled open or closed to reveal the metadata for files and folders.
|
||||
|
||||
### Code Example (Python Script to Export Metadata)
|
||||
|
||||
Here’s a Python script that will scan a directory and gather the metadata:
|
||||
|
||||
```python
|
||||
import os
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
def get_file_metadata(file_path):
|
||||
stats = os.stat(file_path)
|
||||
return {
|
||||
"name": os.path.basename(file_path),
|
||||
"size": stats.st_size,
|
||||
"creation_date": datetime.fromtimestamp(stats.st_ctime).strftime('%Y-%m-%d %H:%M:%S'),
|
||||
"modified_date": datetime.fromtimestamp(stats.st_mtime).strftime('%Y-%m-%d %H:%M:%S'),
|
||||
"permissions": oct(stats.st_mode)[-3:],
|
||||
"is_directory": os.path.isdir(file_path)
|
||||
}
|
||||
|
||||
def build_tree(directory):
|
||||
directory_tree = []
|
||||
for root, dirs, files in os.walk(directory):
|
||||
root_metadata = get_file_metadata(root)
|
||||
tree_item = {
|
||||
"path": root,
|
||||
"metadata": root_metadata,
|
||||
"files": [],
|
||||
"subfolders": []
|
||||
}
|
||||
|
||||
# Get files in the current folder
|
||||
for file in files:
|
||||
file_path = os.path.join(root, file)
|
||||
file_metadata = get_file_metadata(file_path)
|
||||
tree_item["files"].append(file_metadata)
|
||||
|
||||
# Get subfolders (recursive)
|
||||
for dir in dirs:
|
||||
dir_path = os.path.join(root, dir)
|
||||
dir_metadata = get_file_metadata(dir_path)
|
||||
tree_item["subfolders"].append(build_tree(dir_path)[0]) # Recursively add subfolders
|
||||
|
||||
directory_tree.append(tree_item)
|
||||
return directory_tree
|
||||
|
||||
def save_to_json(data, filename="directory_structure.json"):
|
||||
with open(filename, "w") as f:
|
||||
json.dump(data, f, indent=4)
|
||||
|
||||
# Example usage
|
||||
directory = "/path/to/your/directory" # Change this to your directory
|
||||
tree_data = build_tree(directory)
|
||||
save_to_json(tree_data)
|
||||
```
|
||||
|
||||
### Explanation:
|
||||
|
||||
1. **`get_file_metadata`**: This function collects metadata for a file or folder (like creation and modification dates, size, permissions, etc.).
|
||||
2. **`build_tree`**: This function uses `os.walk()` to traverse the directory and construct a tree with file metadata and subdirectories.
|
||||
3. **`save_to_json`**: This function saves the gathered data in a JSON file.
|
||||
|
||||
or bash script can be used too
|
||||
|
||||
```sh
|
||||
#!/bin/bash
|
||||
|
||||
# Usage: ./dir_tree.sh /path/to/directory > output.json
|
||||
|
||||
DIR=${1:-.}
|
||||
|
||||
echo "["
|
||||
|
||||
first=1
|
||||
find "$DIR" -print0 | while IFS= read -r -d '' file; do
|
||||
[ $first -eq 0 ] && echo ","
|
||||
first=0
|
||||
|
||||
name=$(basename "$file")
|
||||
size=$(stat -c %s "$file")
|
||||
created=$(stat -c %w "$file") # May be '-' on some systems
|
||||
modified=$(stat -c %y "$file")
|
||||
perms=$(stat -c %a "$file")
|
||||
is_dir=false
|
||||
[ -d "$file" ] && is_dir=true
|
||||
|
||||
# Output as JSON object
|
||||
echo " {"
|
||||
echo " \"path\": \"${file//\"/\\\"}\","
|
||||
echo " \"name\": \"${name//\"/\\\"}\","
|
||||
echo " \"size\": $size,"
|
||||
echo " \"creation_date\": \"${created//\"/\\\"}\","
|
||||
echo " \"modified_date\": \"${modified//\"/\\\"}\","
|
||||
echo " \"permissions\": \"$perms\","
|
||||
echo " \"is_directory\": $is_dir"
|
||||
echo -n " }"
|
||||
done
|
||||
|
||||
echo
|
||||
echo "]"
|
||||
tar
|
||||
```
|
||||
|
||||
### Frontend: Displaying the Tree View
|
||||
|
||||
You can use **HTML, CSS, and JavaScript** to display the file structure and metadata in a tree view. If you're familiar with **React**, it's even easier.
|
||||
|
||||
Here’s an example of how you can structure the tree view with HTML:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>File Explorer</title>
|
||||
<style>
|
||||
.folder { font-weight: bold; cursor: pointer; }
|
||||
.file { font-style: italic; }
|
||||
.metadata { margin-left: 20px; }
|
||||
.hidden { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="tree-view"></div>
|
||||
|
||||
<script>
|
||||
// Sample JSON data (replace with your actual JSON from the Python script)
|
||||
const treeData = [
|
||||
{
|
||||
"path": "/path/to/folder",
|
||||
"metadata": {
|
||||
"name": "folder",
|
||||
"size": 1234,
|
||||
"creation_date": "2025-05-08 14:30:00",
|
||||
"modified_date": "2025-05-08 14:45:00",
|
||||
"permissions": "755",
|
||||
"is_directory": true
|
||||
},
|
||||
"files": [
|
||||
{
|
||||
"name": "file1.txt",
|
||||
"size": 200,
|
||||
"creation_date": "2025-05-08 14:30:00",
|
||||
"modified_date": "2025-05-08 14:40:00",
|
||||
"permissions": "644",
|
||||
"is_directory": false
|
||||
}
|
||||
],
|
||||
"subfolders": []
|
||||
}
|
||||
];
|
||||
|
||||
function createTreeView(data, parentElement) {
|
||||
data.forEach(item => {
|
||||
const folderDiv = document.createElement("div");
|
||||
folderDiv.classList.add("folder");
|
||||
folderDiv.textContent = item.metadata.name;
|
||||
folderDiv.onclick = () => toggleFolder(folderDiv, item);
|
||||
|
||||
const metadataDiv = document.createElement("div");
|
||||
metadataDiv.classList.add("metadata", "hidden");
|
||||
metadataDiv.innerHTML = `
|
||||
<p>Size: ${item.metadata.size} bytes</p>
|
||||
<p>Created: ${item.metadata.creation_date}</p>
|
||||
<p>Modified: ${item.metadata.modified_date}</p>
|
||||
<p>Permissions: ${item.metadata.permissions}</p>
|
||||
`;
|
||||
|
||||
folderDiv.appendChild(metadataDiv);
|
||||
parentElement.appendChild(folderDiv);
|
||||
|
||||
// Recursively add files and subfolders
|
||||
if (item.files.length > 0 || item.subfolders.length > 0) {
|
||||
const subFolderDiv = document.createElement("div");
|
||||
subFolderDiv.classList.add("subfolder");
|
||||
|
||||
item.files.forEach(file => {
|
||||
const fileDiv = document.createElement("div");
|
||||
fileDiv.classList.add("file");
|
||||
fileDiv.textContent = file.name;
|
||||
subFolderDiv.appendChild(fileDiv);
|
||||
});
|
||||
|
||||
item.subfolders.forEach(subfolder => {
|
||||
createTreeView([subfolder], subFolderDiv);
|
||||
});
|
||||
|
||||
folderDiv.appendChild(subFolderDiv);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function toggleFolder(folderDiv, item) {
|
||||
const metadataDiv = folderDiv.querySelector(".metadata");
|
||||
metadataDiv.classList.toggle("hidden");
|
||||
}
|
||||
|
||||
createTreeView(treeData, document.getElementById("tree-view"));
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
### Steps to Implement:
|
||||
|
||||
1. **Data Fetching:** You will need to load your **JSON** file (from the Python script) into the front-end application. This can be done using a simple `fetch()` call or by directly embedding the JSON data.
|
||||
2. **Displaying Metadata:** Each folder and file item can display its name and, when clicked, show the metadata (size, creation date, etc.).
|
||||
3. **Tree View Toggle:** The metadata will be hidden by default and only visible when the folder is toggled.
|
||||
|
||||
### Conclusion:
|
||||
|
||||
By following this method, you can gather all file and folder metadata, export it as JSON, and then visualize the data in a **tree structure** with toggling effects on the front end. This would allow you to review file and folder properties without direct access to the actual files.
|
||||
61
joplin notion extension/linux/Snippets/sed example.md
Normal file
61
joplin notion extension/linux/Snippets/sed example.md
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
sed example
|
||||
|
||||
|
||||
theory
|
||||
grep is powerful along with other unix tools like cut xargs head less etc.
|
||||
awk goes line by line in a file/stdin giving you all the words in variables with like $1 $2 $3 which you can use however you want
|
||||
|
||||
To achieve this using `sed` (Stream Editor), you can use a regular expression pattern to match the text you want to modify and then replace it with the desired output.
|
||||
|
||||
Assuming you want to remove the `.md` from occurrences of patterns like `(sdusyd.md)` within a file and considering your example, we use the following `sed` command:
|
||||
|
||||
```bash
|
||||
sed 's/\(([^)]*)\).md/\1/g' file.txt
|
||||
```
|
||||
|
||||
Here's a breakdown of the command:
|
||||
|
||||
- `sed`: The command to call Stream Editor.
|
||||
- `s/pattern/replacement/`: The substitute command, where `pattern` is the regex pattern you are looking to match, and `replacement` is the text you want to use to replace the matched pattern.
|
||||
- `\(([^)]*)\).md`: This is the regex pattern we are matching.
|
||||
- `\(`: Matches the literal character "(".
|
||||
- `([^)]*)`: Matches and captures any character except `)` zero or more times. This corresponds to your `<string>`.
|
||||
- `\)`: Matches the literal character ")".
|
||||
- `.md`: Matches the string `.md` that we intend to remove.
|
||||
- `\1`: Refers to the first captured group from the match. In this case, it's the string matched by `([^)]*)`, which is `<string>`.
|
||||
- `g`: Global flag to perform the replacement for all occurrences within a line.
|
||||
- `file.txt`: The file in which the replacements should occur.
|
||||
|
||||
|
||||
For example, if `file.txt` contains:
|
||||
|
||||
```text
|
||||
Some text (sdusyd.md) with markdown files and another (anotherfile.md).
|
||||
```
|
||||
|
||||
After running the command, it will output:
|
||||
|
||||
```text
|
||||
Some text (sdusyd) with markdown files and another (anotherfile).
|
||||
```
|
||||
|
||||
**Note**: If you want to directly modify the file (instead of just outputting the modified text to the terminal), you can use the `-i` option for in-place editing with `sed`. Just remember to backup your original files before using `-i`, as it overwrites the original file:
|
||||
|
||||
```bash
|
||||
sed -i 's/\(([^)]*)\).md/\1/g' file.txt
|
||||
```
|
||||
|
||||
This will change `file.txt` in-place.
|
||||
|
||||
- same thing with perl
|
||||
`perl -pe 's/\(([^()]+)\.md\)/\($1\)/g' file.txt` : this will only print output without modifying file
|
||||
`perl -pi -e 's/\(([^()]+)\.md\)/\($1\)/g' test.txt` : this will modify file too
|
||||
|
||||
this worked for me
|
||||
```bash
|
||||
sed -E -i 's/\(([^\)]*)\.md\)/\(\1\)/g' file.txt
|
||||
```
|
||||
|
||||
|
||||
replicating grep with awk
|
||||
`history | awk '/cd/'` will replicate3 `history | grep 'cd'`
|
||||
Loading…
Reference in a new issue