Bash Script交互式mv问题

时间:2015-12-09 17:12:31

标签: bash

我正在使用bash脚本来帮助组织文件,我想使用mv -i来确保我不会写一些重要内容。

脚本现在正在工作,除了-v为mv。

它显示(y / n [n])没有被覆盖的部分,但是然后去了,并且不允许我与它交互。

createList()
{
    ls *.epub | sed 's/-.*//' |uniq >> list.txt
    ls *.mobi | sed 's/-.*//' |uniq >> list2.txt
}

atag()
{
    find /Users/j/Desktop/Source -maxdepth 1 -iname "*.epub" -type f -print0 | xargs -0 -I '{}' tag -a Purple {}
    find /Users/j/Desktop/Source -maxdepth 1 -iname "*.mobi" -type f -print0 | xargs -0 -I '{}' tag -a Purple {}
}

moveEpub()
{
    while read -r line; do
        if [ -d "/Users/j/Desktop/Dest/$line" ]; then
            if [ -d "/Users/j/Desktop/Dest/$line/EPUB" ]; then
                find /Users/j/Desktop/Source/ -maxdepth 1 -iname "*$line*" -and ! -iname ".*$line*" -type f -print0 | xargs -0 -I '{}' mv -i {} /Users/j/Desktop/Dest/"$line"/EPUB/
            else
                mkdir "/Users/j/Desktop/Dest/$line/EPUB"
                find /Users/j/Desktop/Source/ -maxdepth 1 -iname "*$line*" -and ! -iname ".*$line*" -type f -print0 | xargs -0 -I '{}' mv -i {} /Users/j/Desktop/Dest/"$line"/EPUB/
            fi
        fi
    done < "list.txt"
}

moveMobi()
{
    while read -r line; do
        if [ -d "/Users/j/Desktop/Dest/$line" ]; then
            if [ -d "/Users/j/Desktop/Dest/$line/MOBI" ]; then
                find /Users/j/Desktop/Source/ -maxdepth 1 -iname "*$line*" -and ! -iname ".*$line*" -type f -print0 | xargs -0 -I '{}' mv -i {} /Users/j/Desktop/Dest/"$line"/MOBI/
            else
                mkdir "/Users/j/Desktop/Dest/$line/MOBI"
                find /Users/j/Desktop/Source/ -maxdepth 1 -iname "*$line*" -and ! -iname ".*$line*" -type f -print0 | xargs -0 -I '{}' mv --interactive {} /Users/j/Desktop/Dest/"$line"/MOBI/
            fi
        fi
    done < "list2.txt"
}

clear
createList
atag
moveEpub
moveMobi
rm list.txt
rm list2.txt

2 个答案:

答案 0 :(得分:0)

您可以使用内置的find操作-exec,而不是管道xargs

find /Users/j/Desktop/Source/ -maxdepth 1 \
    -iname "*$line*" -and ! -iname ".*$line*" -type f \
    -exec mv -i {} /Users/j/Desktop/Dest/"$line"/EPUB/ \;

答案 1 :(得分:0)

如果您希望mv -i与终端进行交互,则意味着其stdin需要连接到该终端。在这里,有几个地方可以覆盖标准差。

例如:

# THIS LOOP OVERRIDES STDIN
while read -r line
  ...
done <list.txt

...在整个循环期间重定向stdin,因此mv不是从用户读取,而是从list.txt读取。要更改此设置,请使用其他文件描述符:

# This loop uses FD 3 for stdin
while read -r line <&3
  ...
done 3<list.txt

另一个地方是致电xargs。而不是:

# Overrides stdin for xargs and mv to contain output from find
find ... -print0 | xargs -0 -I '{}' mv -i '{}' "$dest"

...使用:

# directly executes mv from find, stdin not modified
find ... -exec mv -i '{}' "$dest" ';'

那就是说,我建议完全放弃list.txtlist2.txt;你根本不需要它们;就此而言,你也不需要find

dest=/Users/j/Desktop/Dest
source=/Users/j/Desktop/Source
moveEpub() {
  local -A finished=( )                    # WARNING: This requires bash 4.0 or newer.
  for name in *.epub; do
    prefix=${name%%-*}                     # remove everything past the first dash
    [[ ${finished[$prefix]} ]] && continue # skip if already done with this prefix
    finished[$prefix]=1                    # set flag to skip other files w/ this prefix
    [[ -d $dest/$prefix ]] || continue     # skip if no directory exists for this prefix
    mkdir -p "$dest/$prefix/EPUB"          # create destination if not existing
    mv -i "$source"/*"$prefix"* "$dest/$prefix/EPUB"
  done
}