Bash:如何处理所有给定的参数并将它们存储到数组中



我是bash脚本的初学者,我在遵循脚本时遇到问题。

我想处理来自标准的所有给定参数。然后我检查这些参数是否是普通的文本文件。如果是,我想将它们存储到数组中,稍后我想遍历整个数组。但是我收到一个错误:单词未扩展在带有文件+=("$@") 的行上我试着像这样写 file=("$@")但随后我在行上收到以下错误:"("意外(期望"fi")

我将不胜感激任何建议。提前谢谢你。

for file in "${argv[@]}"; do
    if [ -d "$file" ] 
    then
        echo "Error: '"$file"' is directory!" > /dev/stderr
    continue
    fi  

    if [[! -f "$file"] || [! -r "$file"]] 
    then
        echo "Error: '"$file"'!" > /dev/stderr
    continue
    fi  
    file "$file" | grep text >& /dev/null
    if [ ! $status ]
    then
    files+=("$@") 
    else
    echo "Error: '"$file"' not a text file!" > /dev/stderr
    fi
done
for file in "${files[@]}"; do
# .....
done

尝试这样做:

#!/bin/bash
files=( )
for file; do
    if ([[ -f "$file && -r "$file" ]] && file "$file" | grep -q -i "text"); then
        files+=( "$file" )
    fi
done
for f in ${files[@]}; do
    # something with "$f"
done

另一个版本,具有错误处理:

#!/bin/bash
files=( )
for file; do
    if [[ ! -f "$file ]]; then
        echo >&2 "$file is not a regular file"
        continue
    fi
    if [[ ! -r "$file ]]; then
        echo >&2 "$file is not readable for $USER"
        continue
    fi
    if ! file "$file" | grep -q -i "text"; then
        echo >&2 "$file is not a text file"
        continue
    fi
    files+=( "$file" )
done
for f in ${files[@]}; do
    # something with "$f"
done

注意

  • argvbash中不存在,for file就足够了
  • 不使用不存在的变量$status,而是使用预定义的变量$?
  • 无需测试最后状态,您可以做一些更短的事情,例如grep -q pattern file && do_something
  • echo >&2的意思是重定向到STDERR

这是我刚刚编写的脚本,似乎按照您的要求进行操作......只需替换..在第三次测试中,无论您需要什么。不幸的是,我从来没有像你上面那样使用数组,所以我只是按照我的方式写的。我希望它有所帮助。只需将其作为 bash {scriptname}.sh 运行即可。任何输入标准的内容都将处理。

#!/bin/bash
checkfile()
{
for i in $token
    do  
        if [ -f "${i}" ]; then
            {
            echo "It's a file"
            }   
        elif [ -d "${i}" ]; then
            {
            echo "It's a directory"
            }       
        elif [ -z "${i}" ]; then
            {
                :
            }
        fi
    done

}
while ( : )
do
    read token
    checkfile
    sleep 2
done

以下是 bash 中的调试输出:

+ read token
a
+ checkfile
+ for i in '$token'
+ '[' -f a ']'
+ '[' -d a ']'
+ echo 'It'''s a directory'
It's a directory
+ sleep 2
+ :
+ read token
b
+ checkfile
+ for i in '$token'
+ '[' -f b ']'
+ echo 'It'''s a file'
It's a file
+ sleep 2
+ :
+ read token
a
+ checkfile
+ for i in '$token'
+ '[' -f a ']'
+ '[' -d a ']'
+ echo 'It'''s a directory'
It's a directory
+ sleep 2
+ :
+ read token

Sputnick的回答是一个很好的解决方案。如果您想坚持自己的实现,请确保更正以下行:

if [[! -f "$file"] || [! -r "$file"]] 

应始终在括号和测试表达式之间留空格:[[ ! -f "$file" ]] 。此外,由于您使用的是 || 运算符,请使用双括号而不是单括号:

if [[ ! -f "$file" ]] || [[ ! -r "$file" ]] 

将行files+=("$@")更改为 files+=( "$file" )files[${#files[@]}]="$file"

不确定您要对status变量执行什么操作。测试[ ! $status ]将返回 True 对于未赋值的status、赋值的变量(如 status= 或任何status=$(command >& /dev/null))。如果要针对 file ... 命令的退出状态进行测试,请使用整数测试而不是字符串比较:if [ $? -eq 0 ]if (($? == 0))

相关内容

  • 没有找到相关文章

最新更新