Xfce Forum

Sub domains
 

You are not logged in.

#1 2016-04-18 12:46:08

yurbev
Member
Registered: 2016-04-18
Posts: 54

Moving Contents of Folders with YAD

Hi,

I want to use this command or a variant with a YAD script:

find . -mindepth 2 -maxdepth 2 -type f -exec mv "{}" . \;

to right-click on a folder or folders and have the top-level contents of that folder or folders moved to the parent folder. As of now the script will move the contents of all folders to the parent directory, even if I only select one or two folders.

Ideally I want the YAD script to ask for confirmation if I want the names of particular folders moved, like so:

#!/bin/bash

if yad \
    --image "dialog-question" \
    --title "Alert" \
    --button=gtk-yes:0 \
    --button=gtk-no:1 \
    --text "Are you sure you want to move the contents of folders 12, folder 18, folder 22?"

then
    find . -mindepth 2 -maxdepth 2 -type f -exec mv "{}" . \;

else
    exit 1
fi

Offline

#2 2016-04-18 13:41:59

ToZ
Administrator
From: Canada
Registered: 2011-06-02
Posts: 10,948

Re: Moving Contents of Folders with YAD

To confirm my understanding via an example:

- in /tmp there are 3 directories: /tmp/a, /tmp/b, and /tmp/c
- each of these directories have files and other subdirectories in them
- you only want to move /tmp/a/file*, /tmp/b/file* and /tmp/c/file* to the /tmp directory
- for one or more of those selected folders
- In thunar, you will be in the /tmp directory. You will select one or more of /tmp/a, /tmp/b, and /tmp/c, select a custom action, prompt to move, and if yes, move the files.

If so, try this script:

#!/bin/sh

# prepare the string format for the yad dialog
for dirs in "$@"
do
    DIRS="$DIRS\n$dirs"
done

# ask for confirmation
if yad \
    --image "dialog-question" \
    --title "Alert" \
    --button=gtk-yes:0 \
    --button=gtk-no:1 \
    --text "Are you sure you want to move the contents of:\n\n$DIRS"

then
    # move files to parent    
    for dir in "$@"
    do
        find "$dir" -mindepth 1 -maxdepth 1 -type f -exec mv "{}" "$dir" . \;
    done
    
else
    # or bow out
    exit 1
fi
exit 0

...with this thunar custom action:
   - Name = <name>
   - Description = <description>
   - Command = /path/to/script %F
   - Icon = <icon>
   - Appearance = Directories only checked

*Please test this with sample/test data first.

BTW, welcome to the forums.


Please remember to mark your thread [SOLVED] to make it easier for others to find
--- How To Ask For Help | FAQ | Developer Wiki  |  Community | Contribute ---

Offline

#3 2016-04-18 17:59:20

yurbev
Member
Registered: 2016-04-18
Posts: 54

Re: Moving Contents of Folders with YAD

Thanks ToZ. Works well, no tweaking needed.

Offline

#4 2016-04-19 01:45:19

Misko_2083
Member
Registered: 2015-10-13
Posts: 191
Website

Re: Moving Contents of Folders with YAD

This is slightly different. I like having the control over what is moved and a working progress bar. smile
Using the temp file over storing the filenames in a variable.
Also if the "filename" exists it will be renamed to "filename-"+1.

#!/bin/bash

# Working dir
PWD=$(pwd)

# Temp file to store the file names
STORE=$(mktemp /tmp/XXXXXXX)

# Gets selected dirs and writes to STORE
for dirs in "$@"
do
   # Finds files in the selected dirs, prints out TRUE for the YAD checklist
   find "${dirs}" -mindepth 1 -maxdepth 1 -type f -printf "TRUE\n%p\n"
done | tee > $STORE

# If the file list is empty
if [[ ! -s "$STORE" ]]; then
   yad --text "No files found" --button=gtk-ok:0
   rm -f $STORE
   exit 0
fi

# Temp file to store the selected file names to move
TEMP=$(mktemp /tmp/XXXXXXX)

# Dialog to select the files to move
yad --list --checklist --width 500 --height 500 --text "Uncheck the files you don't want to move to\n${PWD}" \
    --separator "" --print-column 2 --column "Pick" --column "Files" < "$STORE"  | tee > $TEMP

# If Cancel is clicked
if [[ $? != 0 ]]; then
   rm -f $STORE
   rm -f $TEMP
   exit 0
fi

rm -f $STORE

# Number of selected files
TOTAL="$(wc -l "$TEMP" | cut -d' ' -f1)"

# Set counter
i=0

# Begin
# Reads from the $TEMP file calculates percentage
while read -r line || [[ -n "$line" ]]; do
      ((++i))
      PERCENT=$(($i*100/${TOTAL}))
      echo "#Moving $i/$TOTAL: ${line##*/}"

      sleep 0.2 # Pause between mv, remove/decrease to speed up

      # If the file exists on the path, renames the destination
      # Else just moves the file
      if [[ -e "${PWD}/${line##*/}" ]] ; then
         a=1
         NAME=${line##*/}
         while [[ -e "${PWD}/${NAME}-$a" ]] ; do
             ((++a))
         done
         NAME="$NAME-$a"
         mv "${line}" "${PWD}/${NAME}"
      else
         mv "${line}" "${PWD}/${line##*/}"
      fi

      echo "$PERCENT"
done < "$TEMP" | yad --progress --title="Moving files" --auto-close

rm -f $TEMP

thunar custom action:
   - Name = <name>
   - Description = <description>
   - Command = /path/to/script %F
   - Icon = <icon>
   - Appearance = Directories only checked
Test with sample data.


--------------------------------------------------------------------------


Next script doesn't depend on the file manager.
just cd to the directory in the terminal and run

#!/bin/bash

# Working dir
PWD=$(pwd)

# Temp file to store the dir names
DIRS=$(mktemp /tmp/XXXXXXX)

# Finds all sub directories and
# Asks to select the ones to search in
find . -mindepth 1 -maxdepth 1 -type d -printf "FALSE\n%p\n" \
| yad --list --checklist --width 500 --height 500 --text "Working directory:\n${PWD}\nSelect the sub-directories to search" \
      --print-column 2 --separator "" --column "Pick" --column "Dirs"  > $DIRS

# If Cancel is clicked
if [[ $? != 0 ]]; then
   rm -f $DIRS
   exit 0
fi

# Temp file to store the file names
STORE=$(mktemp /tmp/XXXXXXX)

# Finds files in the selected dirs
while read -r line
  do
    line="$(printf "$line" | cut -c 2-)"
    find "${PWD}${line}" -mindepth 1 -maxdepth 1 -type f -printf "TRUE\n%p\n"
  done < $DIRS | tee > $STORE

rm -f $DIRS

# If the file list is empty
if [[ ! -s "$STORE" ]]; then
   yad --text "No files found" --button=gtk-ok:0
   rm -f $STORE
   exit
fi

# Temp file to store the selected file names to move
TEMP=$(mktemp /tmp/XXXXXXX)

# Dialog to select the file names to move
yad --list --checklist --width 500 --height 500 --text "Uncheck the files you don't want to move to\n${PWD}" \
    --separator "" --print-column 2 --column "Pick" --column "Files" < "$STORE"  | tee > $TEMP

# If Cancel is clicked
if [[ $? != 0 ]]; then
   rm -f $STORE
   rm -f $TEMP
   exit 0
fi

rm -f $STORE

# Number of selected files
TOTAL="$(wc -l "$TEMP" | cut -d' ' -f1)"

# Set counter
i=0

# Begin
# Reads from the $TEMP file calculates percentage
while read -r line || [[ -n "$line" ]]; do
      ((++i))
      PERCENT=$(($i*100/${TOTAL}))
      echo "#Moving $i/$TOTAL: ${line##*/}"
      sleep 0.2

      # If the file exists on the path, renames the destination
      # Else just moves the file
      if [[ -e "${PWD}/${line##*/}" ]] ; then
         a=1
         NAME="${line##*/}"
         while [[ -e "${PWD}/${NAME}-$a" ]] ; do
             ((++a))
         done
         NAME="$NAME-$a"
         mv "${line}" "${PWD}/${NAME}"
      else
         mv "${line}" "${PWD}/${line##*/}"
      fi

      echo "$PERCENT"
done < "$TEMP" | yad --progress --title="Moving" --auto-close

rm -f $TEMP

Finds all sub-dirs and you select which one you would like to search for files.
Always test on the file samples.


Do you want to exit the Circus?
https://www.youtube.com/watch?v=ZJwQicZHp_c

Offline

#5 2016-05-10 23:40:41

Misko_2083
Member
Registered: 2015-10-13
Posts: 191
Website

Re: Moving Contents of Folders with YAD

I've fixed some issues and added some cool stuff like selecting/deselecting all files and an option to change the destination. wink
Yad is a cool toy to play with. It can do more than zenity.

thunar custom action:
   - Name = <name>
   - Description = <description>
   - Command = /path/to/script %F
   - Icon = <icon>
   - Appearance = Directories only checked
Test with sample data.

#!/bin/bash

file_select () {
# Dialog to select the files to move

while read -r line || [[ -n "$line" ]]; do
  if [[ "$SELECT_ALL" = "FALSE" ]]; then
      printf "FALSE\n$line\n"
  else
      printf "TRUE\n$line\n"
  fi
done < "$STORE" \
| yad --list --checklist --title "Move Files" --width 500 --height 500 --window-icon=gnome-folder \
  --text "Pick the files to move\nUncheck the files you don't want to move\n Destination:\n${PWD}" \
  --separator "" --button="$(if [[ "$SELECT_ALL" = "TRUE" ]]; then echo Select None; else echo Select All; fi)!gtk-yes:3" --button="Destination!gnome-folder:2" \
  --button="gtk-ok:0" --button="gtk-cancel:1" \
  --print-column 2 --column "Pick" --column "Files" > $TEMP

ret=$?

if [[ $ret -eq 1 ]]; then
  rm -f $STORE
  rm -f $TEMP
  exit 0
fi

if [[ $ret -eq 2 ]]; then
  BACKUP="$PWD"
  PWD="$(yad --title 'Select Destination' --width=400 --height=500 --file-selection  --directory)"

  if [[ $? -ne 0 ]]; then
  PWD="$BACKUP"
  fi

  file_select
fi

if [[ $ret -eq 3 ]]; then
   if [[ "$SELECT_ALL" = "TRUE" ]]; then
     SELECT_ALL="FALSE"
   else
     SELECT_ALL="TRUE"
   fi
   file_select
fi

}
SELECT_ALL="TRUE"
# Working dir
PWD=$(pwd)

# Temp file to store the file names
STORE=$(mktemp /tmp/XXXXXXX)

# Gets selected dirs and writes to STORE
for dirs in "$@"
do
  # Finds files in the selected dirs, prints out TRUE for the YAD checklist
  find "${dirs}" -mindepth 1 -maxdepth 1 -type f -printf "%p\n"
done > $STORE

# If the file list is empty
if [[ ! -s "$STORE" ]]; then
  yad --text "No files found" --button=gtk-ok:0
  rm -f $STORE
  exit 0
fi

# Temp file to store the selected file names to move
TEMP=$(mktemp /tmp/XXXXXXX)

file_select

rm -f $STORE

# Number of selected files
TOTAL="$(wc -l "$TEMP" | cut -d' ' -f1)"

# Set counter
i=0

# Begin
# Reads from the $TEMP file calculates percentage
while read -r line || [[ -n "$line" ]]; do
  ((++i))
  PERCENT=$(($i*100/${TOTAL}))
  echo "#Moving $i/$TOTAL: ${line##*/}"

  sleep 0.2 # Pause between mv, comment out / decrease to speed up

  # If the file exists on the path, renames the destination
  # Else just moves the file
  if [[ -e "${PWD}/${line##*/}" ]] ; then
     a=1
     NAME=${line##*/}
     while [[ -e "${PWD}/${NAME}-$a" ]] ; do
        ((++a))
     done
     NAME="$NAME-$a"
     mv "${line}" "${PWD}/${NAME}"
  else
     mv "${line}" "${PWD}/${line##*/}"
  fi

  echo "$PERCENT"
done < "$TEMP" | yad --progress --title="Moving files" --width=400 --auto-close

rm -f $TEMP

Do you want to exit the Circus?
https://www.youtube.com/watch?v=ZJwQicZHp_c

Offline

Board footer

Powered by FluxBB