#bash #shell #windows-subsystem-for-linux
#bash #оболочка #windows-subsystem-for-linux
Вопрос:
Совершенно новый .sh
, и я пытаюсь создать резервные копии изображений со старого iPhone, где изображения были помещены в новый каталог на дату. Существуют сотни каталогов, из которых мне нужно делать снимки из каждого и сбрасывать их все в один каталог.
Моя лучшая попытка:
#!/bin/bash
function process () {
a=1
for i in *
do
cp -r i ${dir}
let a=a 1
done
}
#Interview
echo "This script will take the contents of each directory in the current directory and move it's contents into a new directory that you will specify"
echo "Name your new directory"
read dir
#Confirm
read -p "Your new directory will be ${dir}. Continue?" -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]
then
process
fi
Получены ошибки:
massmove.sh: line 1: $'r': command not found
massmove.sh: line 2: $'r': command not found
massmove.sh: line 3: $'r': command not found
massmove.sh: line 4: syntax error near unexpected token `$'{r''
'assmove.sh: line 4: `function process () {
Обновление: улучшено с помощью ответа deefff:
function process () {
for i in */*.*
do
cp -r $i ${dir}
done
}
echo "This script will take the contents of each directory in the current directory and mv it's contents into a new directory that you will specify"
echo "Name your new directory"
read dir
mkdir ${dir}
echo process
Все еще выдает эти ошибки:
massmove.sh: line 2: syntax error near unexpected token `$'{r''
'assmove.sh: line 2: `function process () {
Может ли это быть ошибкой WSL?
Я понимаю, что
cp */*.* ${dir}
это быстрый и мощный способ выполнить мою задачу, но меня также очень интересует, что вызывает ошибки.
Комментарии:
1. Наличие r в сообщении об ошибке указывает на то, что в вашем файле скрипта есть окончания строк в стиле Windows.
Ответ №1:
*
будет соответствовать каждой записи, включая каталоги, поэтому в его текущем виде он скопирует всю структуру каталогов, что, я полагаю, не то, что вы хотите. Кроме того, вы должны ссылаться на переменную i
, как $i
в cp
команде. Кроме того, a
переменная кажется бессмысленной. Попробуйте сделать это так:
function process () {
for i in */*.*
do
cp $i ${dir}
done
}
На самом деле, я только что понял, что это тоже должно сработать:
cp */*.* ${dir}
Ответ №2:
Пожалуйста, смотрите Мой сценарий ниже.
В основном он имеет 3 функции: menu, prnt (для печати строк с датой) и process (для обработки файлов). В нем есть меню, которое работает с опциями. Надеюсь, вам понравится.
Приветствия !!
Gaurav
#!/bin/bash
curdir=`pwd` # Take the current directory
# To print out logs on the screen, with date and time !!!
prnt ()
{
d=`date "%d-%m-%y "%T` # Take the date string using bash date function.
echo "$d|$1" # Whenever prnt is called, it will echo back, date plus the line passed to it, in nice date|line format.
}
# Menu for the whole operation. This is just the definition. Its being called from the bottom of the script.
menu()
{
# Specially made for you my friend !!
echo ; echo ; prnt " <<!!*** .. params_noob's file copier .. ***!!>>" ; echo ; echo
echo ; prnt "Currently we are in $curdir" ; echo
prnt "Enter the directory, where you would like to move files (Please enter full path and system will create it): " ; echo
read dir ; mkdir $dir 2>/dev/null # Read directory and make it. I am putting all errors to /dev/null. If directory is there, its there, don't want blabber. If not, then create it.
echo ;prnt "Entered directory is "$dir"" ; echo
prnt "Type y to go ahead OR n to start over again.." ; echo
read ans # I have read the answer here
# A simple menu using case function of bash.
case $ans in
y)
echo ; prnt "You have entered yes, to move ahead" ; echo
prnt "processing files now...."
process $dir # Here i am calling the process function.
;;
n)
echo ; prnt "Starting over.. " ; echo
menu # Here i am calling the menu itself, again.
;;
0)
echo ; prnt "Exiting now.. " ; echo
exit # Now exiting the script.
;;
*)
# This one is just to let you know, if you enter anything else than y,n or 0.
echo ; prnt "Invalid input. Please enter y or n or 0 !!" ; echo
;;
esac # Menu using case function ends with esac here.
}
# Function to process and move the files to the desired location.
process()
{
# Took the argument passed to this function into variable "td" [target dirctory].
td="$1"
# Using find command here to find all files. You an replace '-type f' with '-name "*.pic"' or '-name "*.jpg"' -- you get the picture - right?
find $curdir -type f | while read file # Feeding output of find to a while loop.
do
cp $file $td/
done
a=`ls -lrt $td/* |wc -l` # Now taking word count of all the files copied.
# Some more echo and priting.. just for aesthetics.. :)
echo ; echo ; prnt " **** COPIED $a FILES from [$curdir] to [$td] ****" ; echo ; echo
echo ; echo ; ls -lrtha $td|head -10 ; echo ; echo
exit # Script exits after processing the files. You can replace exit with menu, to go back to menu again.
}
#
##
###
####
#####
#################################################################
clear ; menu ### The main menu is being called from this line. I clear the screen first. Looks more professional :)
#################################################################
# FINISH # All done !!
enter code here
Ответ №3:
Попробуйте что-то вроде этого:
function process () {
for file in *; do
if [[ ${file} != ${dir} ]]; then
cp -r ${file} ${dir}
fi
done
}
Кроме того, не забудьте создать каталог перед вызовом функции ‘process’:
echo "Name your new directory: "
read dir
mkdir ${dir}