vedranvinko

Untitled

Dec 17th, 2025
281
1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 3.53 KB | None | 1 0
  1. #!/bin/bash
  2.  
  3. print_usage() {
  4.     echo "Usage:"
  5.     echo "  collect [-o] [-m] [-i] range file"
  6.     echo "  Examples:"
  7.     echo "    collect 1,3 file.txt             # Copy lines to clipboard"
  8.     echo "    collect -o 1,3 file.txt          # Print lines to stdout"
  9.     echo "    collect -m 1,3:5,7:9,9 file.txt  # Multiple ranges, separated by ':'"
  10.     echo "    collect -i 1,3 file.txt          # Inverse selection (all except lines 1-3)"
  11.     exit 1
  12. }
  13.  
  14. validate_range() {
  15.     local range=$1
  16.     local file=$2
  17.     local total_lines=$(wc -l < "$file")
  18.  
  19.     if ! [[ $range =~ ^[0-9]+(,[0-9]+)?$ ]]; then
  20.         echo "Error: Invalid range format '$range'. Expected format: n or n,m"
  21.         return 1
  22.     fi
  23.  
  24.     IFS=',' read -r start end <<< "$range"
  25.     if [ -z "$end" ]; then
  26.         end=$start
  27.     fi
  28.  
  29.     if [ "$start" -gt "$end" ]; then
  30.         echo "Error: Invalid range '$range'. Start line must be less than or equal to end line."
  31.         return 1
  32.     fi
  33.  
  34.     if [ "$start" -eq 0 ] || [ "$end" -gt "$total_lines" ]; then
  35.         echo "Error: Range '$range' is out of bounds. File has $total_lines lines."
  36.         return 1
  37.     fi
  38.  
  39.     return 0
  40. }
  41.  
  42. process_range() {
  43.     local range=$1
  44.     local file=$2
  45.     local inverse=$3
  46.     local total_lines=$(wc -l < "$file")
  47.  
  48.     if [ "$inverse" = true ]; then
  49.         IFS=',' read -r start end <<< "$range"
  50.         if [ -z "$end" ]; then
  51.             end=$start
  52.         fi
  53.  
  54.         if [ "$start" -gt 1 ]; then
  55.             sed -n "1,$((start-1))p" "$file"
  56.         fi
  57.  
  58.         if [ "$end" -lt "$total_lines" ]; then
  59.             sed -n "$((end+1)),$((total_lines))p" "$file"
  60.         fi
  61.     else
  62.         sed -n "${range}p" "$file"
  63.     fi
  64. }
  65.  
  66. if [ "$#" -lt 2 ]; then
  67.     print_usage
  68. fi
  69.  
  70. output_mode=false
  71. multi_range=false
  72. inverse_mode=false
  73.  
  74. while getopts "omi" opt; do
  75.     case ${opt} in
  76.         o )
  77.             output_mode=true
  78.             ;;
  79.         m )
  80.             multi_range=true
  81.             ;;
  82.         i )
  83.             inverse_mode=true
  84.             ;;
  85.         \? )
  86.             print_usage
  87.             ;;
  88.     esac
  89. done
  90. shift $((OPTIND -1))
  91.  
  92. if [ "$#" -ne 2 ]; then
  93.     print_usage
  94. fi
  95.  
  96. ranges=$1
  97. file=$2
  98.  
  99. if [ ! -f "$file" ]; then
  100.     echo "Error: File '$file' does not exist."
  101.     exit 1
  102. fi
  103.  
  104. if [ "$multi_range" = true ]; then
  105.     IFS=':' read -ra RANGE_ARRAY <<< "$ranges"
  106.     for range in "${RANGE_ARRAY[@]}"; do
  107.         if ! validate_range "$range" "$file"; then
  108.             exit 1
  109.         fi
  110.     done
  111. else
  112.     if ! validate_range "$ranges" "$file"; then
  113.         exit 1
  114.     fi
  115. fi
  116.  
  117. if [ "$output_mode" = false ]; then
  118.     if ! command -v xclip &> /dev/null; then
  119.         echo "Error: xclip could not be found. Please install xclip."
  120.         exit 1
  121.     fi
  122. fi
  123.  
  124. if [ "$inverse_mode" = true ] && [ "$multi_range" = true ]; then
  125.     echo "Error: Inverse selection (-i) cannot be used with multiple ranges (-m)"
  126.     exit 1
  127. fi
  128.  
  129. temp_file=$(mktemp)
  130.  
  131. if [ "$multi_range" = true ]; then
  132.     for range in "${RANGE_ARRAY[@]}"; do
  133.         process_range "$range" "$file" false >> "$temp_file"
  134.     done
  135. else
  136.     process_range "$ranges" "$file" "$inverse_mode" >> "$temp_file"
  137. fi
  138.  
  139. if [ "$output_mode" = true ]; then
  140.     cat "$temp_file"
  141. else
  142.     cat "$temp_file" | xclip -selection clipboard
  143.     if [ "$inverse_mode" = true ]; then
  144.         echo "All lines except $ranges from file '$file' have been copied to the clipboard."
  145.     else
  146.         echo "Lines $ranges from file '$file' have been copied to the clipboard."
  147.     fi
  148. fi
  149.  
  150. rm "$temp_file"
Advertisement