You are not logged in.
^ that is probably a better approach to this for sure johnraff, i will have to look into that.
Just playing around with your suggestion and this one liner finds all text files in a folder.
file --mime * | grep "text"
edit: this one a bit better.
file --mime-type * | grep "text" | awk '{print $1}' ORS=' ' | tr -d {[:]}
Bit more progress using mv
#!/usr/bin/env bash
set -e
find_files=$(file --mime-type $HOME/Downloads/* | grep text | awk '{print $1}' ORS=' ' | tr -d {[:]})
move_files () {
mv $find_files $HOME/Documents/
}
move_files
much simpler it seems so far.
Last edited by clusterF (2019-12-12 12:14:26)
Offline
^ until one runs into file names with spaces....?
Offline
^Yes that.
Also, 'file --mime-type --brief' (as I suggested above) might be easier for a script to use, possibly no need to call grep.
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
^Yes that.
Also, 'file --mime-type --brief' (as I suggested above) might be easier for a script to use, possibly no need to call grep.
youtube-dl likes to put spaces in the file names when it downloads, so i probably need to stop that from happening somehow as normally i dont allow spaces in file names. edit: seems there is a flag "--restrict-filenames" in youtube-dl for us unix users which will put underscores where white spaces are.
if i use the --brief flag i dont get the filename just the file attributes eg; for .txt it will "text/plain"
file --mime-type --brief $HOME/Downloads/FILE | grep text | awk '{print $1}' ORS=' ' | tr -d {[:]}
text/plain
and if i leave out "grep text" it just grabs all filenames and attributes in the folder.
Last edited by clusterF (2019-12-13 10:48:34)
Offline
^While it's probably good practice to avoid putting spaces in filenames, as you've found files that come from elsewhere are outside your control. For this reason it's even more important to write scripts which can handle such names. Quoting of variables, use of null delimiters... plenty of testing with nasty filenames, lots of googling, it's more work, but worth it in the end.
Oh, maybe rather than grabbing a whole glob and running it through a series of piped commands all at once, as in
find_files=$(file --mime-type $HOME/Downloads/* | grep text | awk '{print $1}' ORS=' ' | tr -d {[:]})
it might be easier to use a "for" loop, so you can focus on each file individually, something like:
for file in $HOME/Downloads/*
do
type=$( file --mime-type --brief "$file" )
[[ $type = <what I want> ]] || continue
< add "$file" to a list, or just mv it right away >
< whatever... >
done
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
Ok thanks for that johnraff, i will have to play around with this a bit more.
Offline
something like this for text files?
#!/usr/bin/env bash
for file in $HOME/Downloads/*
do
type=$( file --mime-type --brief "$file" )
[[ $type = text/plain ]] || continue
mv $file $HOME/Documents/
done
how would this be implemented to cater for multiple file types in the same script though, eg audio/mpeg, application/zip etc etc? I like functions so my first thought would be to put that script in separate functions and call them from a menu?
edit: answering my own question maybe.
#!/usr/bin/env bash
sort_folder=$"$HOME/Downloads/*"
docs () {
for file in $sort_folder
do
type=$( file --mime-type --brief "$file" )
[[ $type = text/plain ]] || continue
mv $file $HOME/Documents/
done
}
echo "Bash Menu To Clean Up The Downloads Folder"
PS3='Please enter a number of your choice: '
options=("Documents" "Music" "Videos" "Pictures" "Quit")
select opt in "${options[@]}"
do
case $opt in
"Documents")
docs
;;
"Quit")
break
;;
*) echo "invalid option $REPLY";;
esac
done
Last edited by clusterF (2019-12-14 12:23:56)
Offline
Although I would use something like "f" or "FILE" instead of "file", which is a reserved word. Just in case.
Be Excellent to Each Other...
The Bunsenlabs Lithium Desktop » Here
FORUM RULES and posting guidelines «» Help page for forum post formatting
Artwork on DeviantArt «» BunsenLabs on DeviantArt
Offline
Although I would use something like "f" or "FILE" instead of "file", which is a reserved word. Just in case.
camel case might be better perhaps?
Offline
...
camel case might be better perhaps?
Stand well clear while the haters weigh in! Some style guides say not to use camelCase in bash scripts.
Be Excellent to Each Other...
The Bunsenlabs Lithium Desktop » Here
FORUM RULES and posting guidelines «» Help page for forum post formatting
Artwork on DeviantArt «» BunsenLabs on DeviantArt
Offline
What damo said about "file".
And don't forget to quote variables if you want spaces in filenames to work:
mv "$f" "$HOME/Documents/"
(Inside [[ ... ]] it's not usually necessary, but doesn't hurt.)
If you wanted to get fancy about destinations for different file types you could make an associative array.
(man bash )
eg
declare -A destination
destination=([text/plain]="$HOME/Documents" [audio/mpeg]="$HOME/Music" ) # etc
for f in "$HOME/Downloads"/* # don't quote the blob!
do
type=$( file --mime-type --brief "$f" )
[[ -n ${destination[$type]) ]] || continue
mv "$f" "${destination[$type]}"
done
But this is completely untested.
I recommend the package shellcheck and use it all the time. Once installed, you can get a "Lint" (or possibly other name) item in geany's "build" menu.
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
@ damo, well im not a very stylish person to begin with . Google style guide?
@ johnraff, associative arrays looks interesting. Thanks again.
Offline