A utility to mark and operate on files in the shell.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
3.9 KiB

  1. #!/bin/sh
  2. : <<=cut
  3. =pod
  4. =head1 NAME
  5. marks - a tool for marking and acting on file paths
  6. =head1 SYNOPSIS
  7. marks add <path> # Add a file path to the mark list
  8. marks + <path> # Shorthand for add
  9. marks remove <path> # Remove a file path from the mark list
  10. marks - <path> # Shorthand for remove
  11. marks clear # Remove all marks from list
  12. marks ls # List current marks
  13. marks cp # Copy marked files to current directory
  14. marks mv # Move files to current directory and unmark
  15. marks each <command> # Execute command with each marked file as parameter
  16. marks -h # Print help message
  17. =head1 DESCRIPTION
  18. marks stores a list of marked file paths in an SQLite database called marks.db
  19. in the user's home directory. Once marked, files can be copied, moved, listed,
  20. or passed as parameters to arbitrary shell commands.
  21. Commands are intended to be invoked as subcommands of mark(1), in the style of
  22. git(1).
  23. =head1 COMMANDS
  24. =head2 marks-add, marks +
  25. Add one or more paths to the mark list. Relative paths will be stored by their
  26. absolute location. Repeated commands are idempotent - a path can only appear
  27. once in the mark list.
  28. C<marks +> is a convenience shorthand for C<marks add>.
  29. =head2 mark-remove
  30. Remove one or more paths from the mark list. Relative paths will be resolved
  31. to their absolute location before the list is searched.
  32. =head2 marks-clear
  33. Clear the entire mark list.
  34. =head2 marks-ls
  35. List all currently marked paths, one line per path.
  36. =head2 marks-ls --print0
  37. List all currently marked paths, separated by null characters, for use when
  38. piping to C<xargs -0> or other commands which expect null-terminated file
  39. lists. Analogous to C<find -print0>. This is useful where filenames contain
  40. whitespace, quotes, etc.
  41. =head2 marks-cp
  42. Copy all marked paths to the current working directory.
  43. =head2 marks-mv
  44. Move all marked paths to the current working directory, and remove them from
  45. the mark list.
  46. =head2 marks-each
  47. Execute the provided command once per marked path, with the path as a
  48. parameter, and print any output from the command.
  49. This is crudely analogous to C<xargs>. While good enough for simple commands,
  50. it's likely to break in more complex cases, and may be slow for large mark
  51. lists. Consider using marks-ls --print0 and xargs(1) instead.
  52. =head1 SEE ALSO
  53. App::MarkFiles
  54. =head1 LICENSE
  55. marks is free software; you can redistribute it and/or modify
  56. it under the terms of the GNU General Public License as published by
  57. the Free Software Foundation, version 2 of the License.
  58. =head1 AUTHOR
  59. Brennen Bearnes
  60. =cut
  61. print_help() {
  62. echo "$0 - mark and operate on files"
  63. echo
  64. echo "Usage: marks [command] [args]"
  65. echo " marks - List current marks (shortcut for mark ls)"
  66. echo " marks add [path] - Add a file path to the mark list"
  67. echo " marks + [path] - Shorthand for add"
  68. echo " marks remove [path] - Remove a file path from the mark list"
  69. echo " marks - [path] - Shorthand for remove"
  70. echo " marks clear - Clear mark list"
  71. echo " marks cp - Copy marked files to current directory"
  72. echo " marks each [cmd] - Execute command for each marked file"
  73. echo " marks ls - List current marks"
  74. echo " marks mv - Move files to current directory and unmark"
  75. echo " marks -h - Print this help message"
  76. }
  77. if [ $# -lt 1 ]; then
  78. # No arguments - let's just list the existing marks:
  79. exec mark-ls
  80. elif [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
  81. print_help
  82. exit 0
  83. elif [ "$1" = '+' ]; then
  84. subprog="marks-add"
  85. elif [ "$1" = '-' ]; then
  86. subprog="marks-remove"
  87. else
  88. subprog="marks-$1"
  89. fi
  90. # Make sure that the subcommand we're trying to run exists:
  91. command -v "$subprog" >/dev/null 2>&1 || {
  92. echo "marks: '$1' is not a marks command."
  93. echo
  94. print_help
  95. exit 1
  96. }
  97. # Get rid of subcommand name from arguments:
  98. shift
  99. exec "$subprog" "$@"