Automatinis tekstinių failų apdorojimas ir sujungimas
Įvadas
Neseniai man prireikė specifinio scenarijaus, kuris leistų iš įvairių
kataloguose esančių tekstinių (.txt) failų surinkti informaciją,
sujungti ją į vieną Markdown (.md) failą, surūšiuoti ir pašalinti
dublikatus. Ši užduotis reikalavo automatizavimo, kad būtų galima
efektyviai apdoroti didelį kiekį duomenų. Todėl parašiau bash
skriptą, kuris atliko šią užduotį puikiai.
Kaip veikia scenarijus
Šis scenarijus leidžia vartotojui pasirinkti katalogą iš $HOME
aplanko ir pasirinkti, kurie tekstiniai failai turi būti sujungti. Visi
pasirinkti failai yra apdorojami, kad būtų surinktos visos eilutės,
kurios vėliau yra surūšiuojamos ir pašalinami dublikatai. Galutinis
rezultatas yra išsaugomas kaip Markdown failas su tam tikromis
metaduomenų žymomis.
Scenarijaus veikimo žingsniai
- Katalogo pasirinkimas: Vartotojui pateikiamas sąrašas katalogų, esančių
$HOME
aplanke. Jei vartotojas nesirenka jokio katalogo ir tiesiog paspaudžiaEnter
, pasirenkamas numatytasis katalogas ($HOME/Dokumentai
). - Tikrinimas, ar katalogas egzistuoja: Patikrinama, ar pasirinktasis katalogas egzistuoja. Jei ne, scenarijus baigia darbą.
- Tekstinių failų sąrašo sudarymas: Scenarijus suranda visus .txt failus pasirinktuose kataloguose ir pateikia juos vartotojui su numeracija, kad būtų galima pasirinkti konkrečius failus.
- Failų pasirinkimas: Vartotojas gali įvesti numerius, nurodydamas, kurie failai turi būti sujungti. Leidžiama pasirinkti tiek atskirus failus, tiek diapazoną (pvz., 1-5).
- Pasirinktų failų apdorojimas: Pasirinkti failai yra atidaromi, jų turinys skaitomas ir visos eilutės surenkamos į vieną sąrašą. Iš šio sąrašo pašalinami dublikatai ir eilutės surūšiuojamos.
- Rezultatų išsaugojimas: Surūšiuotos ir unikalios eilutės įrašomos į naują Markdown failą su metaduomenų žymomis (
tags: audioknygos, sąrašas
). Kiekviena eilutė yra sunumeruojama.
#!/bin/bash
# Funkcija diapazono pasirinkimui
select_range() {
local range_start range_end
read -p "Įveskite diapazoną (pvz., 1-5) arba atskirus skaičius (pvz., 1 3 5): " selection
# Išvalome galimų pasirinkimų masyvą
valid_selections=()
for part in $selection; do
if [[ $part =~ ^([0-9]+)-([0-9]+)$ ]]; then
range_start=${BASH_REMATCH[1]}
range_end=${BASH_REMATCH[2]}
if [ $range_start -ge 0 ] && [ $range_end -lt ${#txt_files[@]} ]; then
for ((i=range_start; i<=range_end; i++)); do
valid_selections+=("$i")
done
else
echo "Netinkamas diapazonas: $part"
fi
elif [[ $part =~ ^[0-9]+$ ]] && [ $part -ge 0 ] && [ $part -lt ${#txt_files[@]} ]; then
valid_selections+=("$part")
else
echo "Netinkamas pasirinkimas: $part"
fi
done
}
# Pasirinkite katalogą pradedantį nuo $HOME/
default_dir="$HOME/Dokumentai" # Numatytasis katalogas
directories=("$HOME"/*/)
echo "Pasirinkite katalogą, pradedantį nuo \$HOME/ (spauskite Enter norėdami pasirinkti $default_dir):"
for i in "${!directories[@]}"; do
echo "$i) ${directories[$i]}"
done
read -p "> " dir_choice
if [ -z "$dir_choice" ]; then
DIRECTORY="$default_dir"
elif [[ $dir_choice =~ ^[0-9]+$ ]] && [ $dir_choice -ge 0 ] && [ $dir_choice -lt ${#directories[@]} ]; then
DIRECTORY="${directories[$dir_choice]}"
else
echo "Netinkamas pasirinkimas."
exit 1
fi
# Patikrinkite, ar katalogas egzistuoja
if [ ! -d "$DIRECTORY" ]; then
echo "Katalogas $DIRECTORY neegzistuoja"
exit 1
fi
# Gauti visus .txt failus kataloge
txt_files=("$DIRECTORY"/*.txt)
# Patikrinkite, ar yra .txt failų
if [ ${#txt_files[@]} -eq 0 ]; then
echo "Nėra .txt failų kataloge $DIRECTORY"
exit 1
fi
# Atspausdinti failų sąrašą su numeracija
echo "Pasirinkite failus sujungimui (įveskite numerius, atskirtus tarpais arba diapazoną):"
for i in "${!txt_files[@]}"; do
echo "$i) ${txt_files[$i]}"
done
# Nuskaityti vartotojo įvestį
valid_selections=()
select_range
# Jei nėra tinkamų pasirinkimų, leisti bandyti dar kartą
while [ ${#valid_selections[@]} -eq 0 ]; do
select_range
done
# Surinkti pasirinktas eilutes
all_lines=()
for i in "${valid_selections[@]}"; do
while IFS= read -r line; do
all_lines+=("$line")
done < "${txt_files[$i]}"
done
# Pašalinti dublikatus
mapfile -t uniq_lines < <(printf '%s\n' "${all_lines[@]}" | sort -u)
# Surūšiuoti eilutes
IFS=$'\n' sorted_lines=($(sort <<<"${uniq_lines[*]}"))
unset IFS
# Pridėti pradines eilutes į naują failą
output_file="$HOME/Obsidian/notes/audioknygos_$(date +%Y%m%d_%H%M%S).md"
{
echo "---"
echo "tags:"
echo " - audioknygos"
echo " - sąrašas"
echo "---"
echo
# Numeruoti kiekvieną eilutę
for i in "${!sorted_lines[@]}"; do
echo "$(($i + 1)). ${sorted_lines[$i]}"
done
} > "$output_file"
echo "Sujungti ir surūšiuoti failai įrašyti į $output_file"
Ką dar būtų galima patobulinti
Nors scenarijus veikia gerai, yra keli dalykai, kuriuos būtų galima patobulinti:
- Vartotojo sąsaja: Galima sukurti interaktyvią vartotojo sąsają su dialogų langais, kurie padarytų pasirinkimų procesą patogesnį.
- Failų filtravimas: Galima pridėti galimybę filtruoti failus pagal tam tikrus kriterijus, pavyzdžiui, pagal jų dydį ar sukūrimo datą.
- Išplėstinis duomenų apdorojimas: Galima pridėti galimybę naudoti sudėtingesnius duomenų apdorojimo algoritmus, tokius kaip natūraliosios kalbos apdorojimas, norint išvalyti ar transformuoti tekstą prieš jį sujungiant.
- Lankstesnės išvesties formatavimas: Galima suteikti vartotojui daugiau pasirinkimų, kaip formatuoti išvestį, pavyzdžiui, pasirinkti tarp skirtingų formatų (Markdown, HTML, paprastas tekstas).
Šis scenarijus parodė, kaip galima automatizuoti kasdienes užduotis naudojant bash
skriptus, padedant sutaupyti laiko ir pastangų. Tikiuosi, kad šis
įrašas ir scenarijus bus naudingi kitiems, susiduriantiems su panašiomis
užduotimis!
Komentarai
Rašyti komentarą