Bash命令在脚本中不起作用,但在控制台中 [英] Bash command does not work in script but in console

查看:73
本文介绍了Bash命令在脚本中不起作用,但在控制台中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在脚本中运行了两个命令,我想检查一下Directoy中的所有文件是否都是媒体:

I have running the two commands in a script where I want to check if all files in a directoy are media:

1 All_LINES=$(ls -1 | wc -l)
2 echo "Number of lines: ${All_LINES}"
3
4 REACHED_LINES=$(ls -1 *(*.JPG|*.jpg|*.PNG|*.png|*.JPEG|*.jpeg) | wc -l)
5 echo "Number of reached lines: ${REACHED_LINES}"

if[...]

在外壳中按顺序运行第4行和第5行,按预期工作,计算以.jpg,.JPG ...结尾的所有文件.

Running line 4 and 5 sequentially in a shell it works as expected, counting all files ending with .jpg, .JPG...

在脚本中一起运行会产生以下错误:

Running all together in a script gives the following error though:

Number of lines: 12
/home/andreas/.bash_scripts/rnimgs: command substitution: line 17: syntax error near unexpected token `('
/home/andreas/.bash_scripts/rnimgs: command substitution: line 17: `ls -1 *(*.JPG|*.jpg|*.PNG|*.png|*.JPEG|*.jpeg) | wc -l)'
Number of reached lines:

可以有人给我解释一下吗?

Could somebody explain this to me, please?

据我所知:

#!/bin/bash

# script to rename images, sorted by "type" and "date modified" and named by current folder

#get/set basename for files
CURRENT_BASENAME=$(basename "${PWD}")
echo -e "Current directory/basename is: ${CURRENT_BASENAME}\n"
read -e -p "Please enter basename: " -i "${CURRENT_BASENAME}" BASENAME
echo -e "\nNew basename is: ${BASENAME}\n"

#start
echo -e "START RENAMING"

#get nr of all files in directory
All_LINES=$(ls -1 | wc -l)
echo "Number of lines: ${All_LINES}"

#get nr of media files in directory
REACHED_LINES=$(ls -1 *(*.JPG|*.jpg|*.PNG|*.png|*.JPEG|*.jpeg) | wc -l)
echo "Number of reached lines: ${REACHED_LINES}"

再次感谢大家,这是我到目前为止的结果.仍有改进的空间,但可以开始测试.

Thanks again guys, this is my result so far. Still room for improvement, but a start and ready to test.

#!/bin/bash

#script to rename media files to a choosable name (default: ${basename} of current directory) and sorted by date modified

#config
media_file_extensions="(*.JPG|*.jpg|*.PNG|*.png|*.JPEG|*.jpeg)"

#enable option extglob (extended globbing): If set, the extended pattern matching features described above under Pathname Expansion are enabled.
#more info: https://askubuntu.com/questions/889744/what-is-the-purpose-of-shopt-s-extglob
#used for regex
shopt -s extglob

#safe and set IFS (The Internal Field Separator): IFS is used for word splitting after expansion and to split lines into words with the read builtin command.
#more info: https://bash.cyberciti.biz/guide/$IFS
#used to get blanks in filenames
SAVEIFS=$IFS;
IFS=$(echo -en "\n\b");

#get and print current directory
basedir=$PWD
echo "Directory:" $basedir

#get and print nr of files in current directory
all_files=( "$basedir"/* )
echo "Number of files in directory: ${#all_files[@]}"

#get and print nr of media files in current directory
media_files=( "$basedir"/*${media_file_extensions} )
echo -e "Number of media files in directory: ${#media_files[@]}\n"

#validation if #all_files = #media_files
if [ ${#all_files[@]} -ne ${#media_files[@]} ]
then
  echo "ABORT - YOU DID NOT REACH ALL FILES, PLEASE CHECK YOUR FILE ENDINGS"
  exit
fi

#make a copy
backup_dir="backup_95f528fd438ef6fa5dd38808cdb10f"
backup_path="${basedir}/${backup_dir}"
mkdir "${backup_path}"
rsync -r "${basedir}/" "${backup_path}" --exclude "${backup_dir}"
echo "BACKUP MADE"

echo -e "START RENAMING"

#set new basename
basename=$(basename "${PWD}")
read -e -p "Please enter file basename: " -i "$basename" basename
echo -e "New basename is: ${basename}\n"

#variables
counter=1;
new_name="";
file_extension="";

#iterate over files
for f in $(ls -1 -t -r *${media_file_extensions})
do
  #catch file name
  echo "Current file is:           $f"
  #catch file extension
  file_extension="${f##*.}";
  echo "Current file extension is: ${file_extension}"
  #create new name
  new_name="${basename}_${counter}.${file_extension}"
  echo "New name is:               ${new_name}";
  #rename file
  mv $f "${new_name}";
  echo -e "Counter is:                ${counter}\n"

  ((counter++))
done

#get and print nr of media files before
echo "Number of media files before: ${#media_files[@]}"
#get and print nr of media files after
media_files=( "$basedir"/*${media_file_extensions} )
echo -e "Number of media files after: ${#media_files[@]}\n"

#delete backup?
while true; do
    read -p "Do you wish to keep the result? " yn
    case $yn in
        [Yy]* ) rm -r ${backup_path}; echo "BACKUP DELETED"; break ;;
        [Nn]* ) rm -r !(${backup_dir}); rsync -r "${backup_path}/" "${basedir}"; rm -r ${backup_path}; echo "BACKUP RESTORED THEN DELETED"; break;; 
        * ) echo "Please answer yes or no.";;
    esac
done

#reverse IFS to default
IFS=$SAVEIFS;

echo -e "END RENAMING"

推荐答案

您完全不需要在这里使用 ls .请参见 https://mywiki.wooledge.org/ParsingLs

You don't need to and don't want to use ls at all here. See https://mywiki.wooledge.org/ParsingLs

此外,请勿对您的私有变量使用大写字母.参见正确的Bash和shell脚本变量大写

Also, don't use uppercase for your private variables. See Correct Bash and shell script variable capitalization

#!/bin/bash

shopt -s extglob

read -e -p "Please enter basename: " -i "$PWD" basedir
all_files=( "$basedir"/* )
echo "Number of files: ${#all_files[@]}"

media_files=( "$basedir"/*(*.JPG|*.jpg|*.PNG|*.png|*.JPEG|*.jpeg) )
echo "Number of media files: ${#media_files[@]}"

这篇关于Bash命令在脚本中不起作用,但在控制台中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆