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

  1. Katalogo pasirinkimas: Vartotojui pateikiamas sąrašas katalogų, esančių $HOME aplanke. Jei vartotojas nesirenka jokio katalogo ir tiesiog paspaudžia Enter, pasirenkamas numatytasis katalogas ($HOME/Dokumentai).
  2. Tikrinimas, ar katalogas egzistuoja: Patikrinama, ar pasirinktasis katalogas egzistuoja. Jei ne, scenarijus baigia darbą.
  3. 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.
  4. Failų pasirinkimas: Vartotojas gali įvesti numerius, nurodydamas, kurie failai turi būti sujungti. Leidžiama pasirinkti tiek atskirus failus, tiek diapazoną (pvz., 1-5).
  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.
  6. 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.
bash
#!/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:

  1. Vartotojo sąsaja: Galima sukurti interaktyvią vartotojo sąsają su dialogų langais, kurie padarytų pasirinkimų procesą patogesnį.
  2. Failų filtravimas: Galima pridėti galimybę filtruoti failus pagal tam tikrus kriterijus, pavyzdžiui, pagal jų dydį ar sukūrimo datą.
  3. 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.
  4. 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

Populiarūs šio tinklaraščio įrašai

Configuring a NixOS firewall for everyday use

Setting up syncthing as a service on openSUSE and other Linux distributions

Monitoring SFTP server updates with Python