将.old添加到没有.old的文件中,无法使用哪个变量?

时间:2016-07-25 02:36:03

标签: bash variables grep ls

#!/bin/bash
for filenames in $( ls $1 )
 do
  echo $filenames | grep "\.old$"
   if [ ! $filenames  = 0 ]
    then
     $( mv "$1/$filenames" "$1/$filenames.old" )
   fi
done

所以我认为大部分脚本都有效。它旨在将ls的输出作为第一个参数中输入的目录,并在末尾搜索任何带有.old的文件。然后将重命名任何不包含.old的文件。 该脚本成功重命名文件,但它会将.old添加到已包含扩展名的文件中。我假设if变量是错误的,但我不知道在这种情况下使用哪个变量。

答案就在关键中,但如果有人需要这样做,这是一种更简单的方法:

#!/bin/bash
for filenames in $( ls $1 | grep -v "\.old$" )
do
     $( mv "$1/$filenames" "$1/$filenames.old" )
done

4 个答案:

答案 0 :(得分:3)

使用`find for this

find /directory/here -type f ! -iname "*.old" -exec mv {} {}.old \;

问题原始方法

  • for filenames in $( ls $1 )从不解析ls输出。查看[ this ]
  • 变量不是双引号,比如if [ ! $filenames = 0 ]。这会导致分词。除非您希望分词,否则请使用"$filenames"

所以最终的剧本将是

#!/bin/bash
if [ -d "$1" ]
then
 find "$1" -type f ! -iname "*.old" -exec mv {} {}.old \;
 # use -maxdepth 1 with find if  you don't wish to recursively check subdirectories
else
 echo "Directory : $1 doesn't exist !"
fi

<强>用法

./script '/path/to/directory'

答案 1 :(得分:2)

Don't use ls in scripts.

#!/bin/bash
for filename in "$1"/*
do
  case $filename in *.old) continue;; esac
  mv "$filename" "$filename.old"
done

我更喜欢case而不是if,因为它支持自然和可移植的通配符匹配。 (您也可以使用/bin/sh运行此功能。)如果您想使用if,那就是

if echo "$filename" | grep -q '\.old$'; then

或更多惯用语,但仅限最近的shell,

if [[ "$filename" == *.old ]]; then

答案 2 :(得分:1)

如果简单的shell内置函数可以,您希望避免调用其他实用程序函数。为什么?您调用grep等的每个附加实用程序都会生成并运行在其自己的单独子shell中。 (如果你在循环中为每次迭代产生一个子shell - 事情真的会慢下来)如果shell没有提供一个功能,那么确定...调用实用程序是正确的要做。

如上所述,shell globbing与参数扩展一起使用子字符串删除提供了一个简单的测试,用于确定文件是否具有.old扩展名。您所需要的只是:

for i in "$1"/*; do
    [ "${i##*.}" = "old" ] || mv "$i" "${i}.old"
done

注意:这会跳过将.old扩展名添加到名为'old'的单个文件中,但如果需要可以单独处理 - 不太可能。此外,解决方案使用find也是一个很好的方法)

答案 3 :(得分:-3)

我解决了这个问题,因为我被导师误导了! $?是表示当前在forground中的管道输出的变量(可能是grep)。除

外,新代码未经编辑
if [ ! $? = 0 ]