]> Sergey Matveev's repositories - nnn.git/commitdiff
plugins: cleanfilename: sh->bash and added support for cleaning newline (#923)
authorBenawi Adha <43810055+wustho@users.noreply.github.com>
Sat, 27 Mar 2021 14:06:17 +0000 (21:06 +0700)
committerGitHub <noreply@github.com>
Sat, 27 Mar 2021 14:06:17 +0000 (19:36 +0530)
* plugins: cleanfilename: sh->bash and added support for cleaning newline

* plugins: cleanfilename: sh->bash and added support for cleaning newline

plugins/cleanfilename

index d0a094808036a78499c40f575e05a2fd0815dbc7..ce573fabf3548f152dfb044e091c9e4b9383af9d 100755 (executable)
@@ -1,37 +1,48 @@
-#!/usr/bin/env sh
+#!/usr/bin/env bash
 
 # Description: Clean filename or dirname (either hovered or selections)
-#              to be more shell-friendly.
-#              This script replaces any non A-Za-z0-9._- char
-#              with underscore (_).
+#              to be more shell-friendly. This script cleans
+#              any character which is not A-Za-z0-9._-
+#              and replaces it with underscore (_).
 #
-#              LIMITATION: Won't work with filename that contains newline
+#              It supports cleaning single/double quote, newline,
+#              leading, trailing spaces.
+#
+#              eg.
+#              to be continued (つづく).mp4  -> to_be_continued______.mp4
+#              [work] stuff.txt              -> _work__stuff.txt
+#              home's server                 -> home_s_server
+#                qwe\trty                    -> __qwe_rty
+#
+#              And if there are two almost similar filenames
+#              like: 'asd]f' and 'asd f' which both will be renamed to 'asd_f',
+#              to avoid overwriting, the last file will be prepended by _.
+#              So they will be: 'asd_f' and '_asd_f'
 #
 # Dependencies: sed
 #
-# Shell: POSIX compliant
+# Shell: Bash
 # Author: Benawi Adha
 
 prompt=true
 sel=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
-IFS='
-'
 
 cleanup() {
-    printf "%s" "$1" | sed -e 's/[^A-Za-z0-9._-]/_/g'
+    # printf "%s" "$1" | sed -e 's/[^A-Za-z0-9._-]/_/g'
+    printf "%s" "$1" | sed 's/[^A-Za-z0-9._-]/_/g' | sed ':a;N;$!ba;s/\n/_/g'
 }
 
 if [ -s "$sel" ]; then
-    targets=$(sed -e "s/\\x0/\\n/g;\$a\\" "$sel" | \
-        while read -r i; do
-            basename "$i";
-        done)
+    targets=()
+    while IFS= read -r -d '' i || [ -n "$i" ]; do
+        targets+=( "$(basename "$i")" )
+    done < "$sel"
 else
-    targets=$1
+    targets=("$1")
 fi
 
-for i in $targets; do
-    printf "%s --> %s\n" "$i" "$(cleanup "$i")";
+for i in "${targets[@]}"; do
+    printf "%s -> %s\n" "$i" "$(cleanup "$i")";
 done
 
 if $prompt; then
@@ -48,7 +59,7 @@ if $prompt; then
     esac
 fi
 
-for i in $targets; do
+for i in "${targets[@]}"; do
     if [ "$i" != "$(cleanup "$i")" ]; then
         tmp=''
         if [ -e "$(cleanup "$i")" ]; then