1

I have a script that first move the selected files into a temp directory,scans the directory, takes the largest file and create a new directory with that name, and moving all files to the newly created directory.

but it's crashing when bumping into directories or files containing the ' character, for example the word we're I think it can have something to do with the jfilenameall isn't "quoted" right, and I have tested a few ways, but haven't got it to work.

anybody that knows what I'm doing wrong?

Worth mention is that I'm running this script Via nemo action, so the following command line is executed: script.sh "path/filename1.txt" "path/filename2.txt" ..and so on depending on how many files that was selected in the gui

jdir2="$1"
jdirfirst="${jdir2%/*}"
jdir="$jdirfirst"/
jdir0="$jdirfirst"
tmpdir="$jdir0/tmp.tmp3"
mkdir "$tmpdir"
mv "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$tmpdir"/
                
 jfilenameall=$(basename $(find $tmpdir -maxdepth 1 -type f  -printf "%s\t%p\n" | sort -n | tail -1 | awk '{print $NF}'))
jfilename="${jfilenameall::-4}"
jfilenameextension="$(echo -n $jfilenameall | tail -c 3)"
jfilename=${jdirlast::-4}    
mkdir "$jdir0/$jfilename"
mv "$jdir0/tmp.tmp3/"* "$jdir0/$jfilename/"
10
  • 1
    quote your $(find ...) part like this jfilenameall=$(basename "$(find ... )"). Does that help? Anyways, you're command will also have problems with spaces in filenames like in "we are" to stay with your example ;-) – pLumo Sep 15 '20 at 7:33
  • Note that your script does not copy the files you give it, it moves them. – terdon Sep 15 '20 at 8:16
  • Also, what operating system are you using? Are you on Linux? Can we assume GNU tools? – terdon Sep 15 '20 at 8:21
  • @terdon yes, Linux, move, not copy, my bad .. – JoBe Sep 15 '20 at 8:34
  • 2
    JoBe, don't put yourself down. Stupidity is not lack of knowledge. Stupidity is refusing either to learn or apply knowlege when it has been offered or gained – roaima Sep 15 '20 at 9:45
1

This will do what your question describes (I removed some of the steps you had since they didn't seem necessary). Note that it assumes you are using GNU tools. The main issue was that you weren't double quoting your variables and command substitutions. I also made this work for some weirder file names such as those containing newlines or those starting with -:

#!/bin/bash

## You don't define $jdir0 in your script, so I am assuming you
## do so earlier. I'm setting it to '/tmp' here.
jdir0="/tmp"

## Create a temp dir in $jdir0
tmpdir=$(mktemp -dp "$jdir0")

## Move all arguments passed to the script to the tmp dir,
## this way you don't need to specify $1, $2 etc. The -- ensures
## this will work even if your file names start with '-'.
mv -- "$@" "$tmpdir"/


## Get the largest file's name. Assume GNU find; deal with arbitrary file names,
## including those with spaces, quotes, globbing characters or newlines
IFS= read -r -d '' jfilenameall < <(find "$tmpdir" -maxdepth 1 -type f \
                                        -printf '%s\t%p\0' | sort -zn |
                                        tail -zn1 | cut -f 2-)

## Assume GNU find; deal with arbitrary file names, including those with
## spaces, quotes, globbing characters or newlines
jfilenameall="$(basename "$jfilenameall")"

## Get the extension: whatever comes after the last . in the file name. You don't
## use this anywhere, but maybe you just don't show it. If the file has no extension,
## this variable will be set to the entire file name.
jfilenameextension="${jfilenameall##*.}"

## get the file name without the extension. Don't assume an extension will always be 3 chars
jfilename="${jfilenameall%.*}"

## You don't define $jdir0 in your script. I am assuming you do so earlier
mkdir -p "$jdir0/$jfilename"
mv -- "$tmpdir/"* "$jdir0/$jfilename/"

## remove the now empty tmp dir
rmdir "$tmpdir"
10
  • After defining jfilenameextension you should consider [[ "$jfilenameextension" == "$jfilenameall" ]] && jfilenameextension= to handle the case where there is no dot in the filename. You don't need a corresponding fix for jfilename. – roaima Sep 15 '20 at 8:45
  • @roaima ah yes, thanks. But I also have another issue with the null byte in the substitution. I'll fix both. – terdon Sep 15 '20 at 8:47
  • 1
    @roaima I fixed the other issue (I'd forgotten that bash complains about nulls in command substitutions) but on second thought, I think leaving jfilenameextension be the full name when there's no extension is fine. The variable isn't used anywhere, for one thing, I just included it because it was in the question. – terdon Sep 15 '20 at 8:57
  • @terdon jdir2="$1" jdirfirst="${jdir2%/*}" jdir="$jdirfirst"/ jdir0="$jdirfirst" is how I determine the jdir0, I'm running this script from gui, so the script is executed as: script.sh "filename 1" "filename 2" and so on.. the jfilenameextension is a leftover, and not used in this script – JoBe Sep 15 '20 at 9:02
  • 1
    @JoBe don't worry, that's how we all learn! :) – terdon Sep 15 '20 at 9:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.