在for循环中使用数组,在bash中[重复]

时间:2022-10-30 12:48:29

This question already has an answer here:

这个问题在这里已有答案:

I am currently working on a bash script where I must download files from our mySQL database, host them somewhere different, then update the database with the new location for the image. The last portion is my problem area, creating the array full of filenames and iterating through them, replacing the file names in the database as we go.

我目前正在开发一个bash脚本,我必须从mySQL数据库下载文件,将它们托管在不同的地方,然后使用图像的新位置更新数据库。最后一部分是我的问题区域,创建充满文件名的数组并迭代它们,在我们去的时候替换数据库中的文件名。

For whatever reason I keep getting these kinds of errors:

无论出于何种原因,我都会遇到这些错误:

not found/X2b6qZP.png: 1: /xxx/images/X2b6qZP.png: ?PNG /xxx/images/X2b6qZP.png: 2: /xxx/images/X2b6qZP.png: : not found /xxx/images/X2b6qZP.png: 1: /xxx/images/X2b6qZP.png: Syntax error: word unexpected (expecting ")")

未找到/ X2b6qZP.png:1:/xxx/images/X2b6qZP.png:?PNG /xxx/images/X2b6qZP.png:2:/xxx/images/X2b6qZP.png ::找不到/ xxx / images / X2b6qZP。 png:1:/xxx/images/X2b6qZP.png:语法错误:单词意外(期待“)”)

files=$($DOWNLOADDIRECTORY/*)
files=$(${files[@]##*/})

# Iterate through the file names in the download directory, and assign the new values to the detail table.

for file in "${files[@]}"
    do
        mysql -h ${HOST} -u ${USER} -p${PASSWORD} ${DBNAME}  "UPDATE crm_category_detail SET detail_value = 'http://xxx.xxx.x.xxx/img/$file' WHERE detail_value LIKE '%imgur.com/$file'"
    done

4 个解决方案

#1


2  

whats going on right here?

什么事发生在这里?

files=$($DOWNLOADDIRECTORY/*)

I dont think this is doing what you think it is doing.

我不认为这是在做你认为它正在做的事情。

According to this answer, you want to omit the first $ to get an array of files.

根据这个答案,你想省略第一个$来获取一个文件数组。

files=($DOWNLOADDIRECTORY/*)

I just wrote a sample script

我刚写了一个示例脚本

#!/bin/sh
alist=(/*)
printf '%s\n' "${alist[@]}"

Output

产量

/bin
/boot
/data
/dev
/dist
/etc
/home
/lib
....

#2


3  

You are trying to execute a glob as a command. The syntax to use arrays is array=(tokens):

您正在尝试将glob作为命令执行。使用数组的语法是array =(tokens):

files=("$DOWNLOADDIRECTORY"/*)
files=("${files[@]##*/}")

You are also trying to run your script with sh instead of bash.

您还尝试使用sh而不是bash来运行脚本。

Do not run sh file or use #!/bin/sh. Arrays are not supported in sh.

不要运行sh文件或使用#!/ bin / sh。 sh中不支持数组。

Instead use bash file or #!/bin/bash.

而是使用bash文件或#!/ bin / bash。

#3


2  

Your assignments are not creating arrays. You need arrayname=( values for array ) as the notation. Hence:

您的分配不是创建数组。您需要arrayname =(数组的值)作为表示法。因此:

files=( "$DOWNLOADDIRECTORY"/* )
files=( "${files[@]##*/}" )

The first line will give you all the names in the directory specified by $DOWNLOADDIRECTORY. The second carefully removes the directory prefix. I've used spaces after ( and before ) for clarity; the shell neither requires nor objects to them. I used double quotes around the variable name and expansions to keep things sane when name do contain spaces etc.

第一行将为您提供$ DOWNLOADDIRECTORY指定的目录中的所有名称。第二个小心地删除目录前缀。为了清晰起见,我在之后(和之前)使用了空格; shell既不需要也不反对它们。我在变量名称和扩展周围使用了双引号,以便在名称包含空格等时保持理智。

Although it isn't immediately obvious why you might do this, its advantage over many alternatives is that it preserves spaces etc in file names.

尽管为什么你可能会这样做并不是很明显,但它优于许多替代方案的优势在于它保留了文件名中的空格等。

#4


0  

You could just loop directly over the files:

你可以直接循环遍历文件:

for file in "$DOWNLOADDIRECTORY"/*; do
    file="${file##*/}" # or file=$(basename "$file")
    # MySQL stuff
done

Some quoting added in case of spaces in paths.

如果路径中有空格,则会添加一些引用。

#1


2  

whats going on right here?

什么事发生在这里?

files=$($DOWNLOADDIRECTORY/*)

I dont think this is doing what you think it is doing.

我不认为这是在做你认为它正在做的事情。

According to this answer, you want to omit the first $ to get an array of files.

根据这个答案,你想省略第一个$来获取一个文件数组。

files=($DOWNLOADDIRECTORY/*)

I just wrote a sample script

我刚写了一个示例脚本

#!/bin/sh
alist=(/*)
printf '%s\n' "${alist[@]}"

Output

产量

/bin
/boot
/data
/dev
/dist
/etc
/home
/lib
....

#2


3  

You are trying to execute a glob as a command. The syntax to use arrays is array=(tokens):

您正在尝试将glob作为命令执行。使用数组的语法是array =(tokens):

files=("$DOWNLOADDIRECTORY"/*)
files=("${files[@]##*/}")

You are also trying to run your script with sh instead of bash.

您还尝试使用sh而不是bash来运行脚本。

Do not run sh file or use #!/bin/sh. Arrays are not supported in sh.

不要运行sh文件或使用#!/ bin / sh。 sh中不支持数组。

Instead use bash file or #!/bin/bash.

而是使用bash文件或#!/ bin / bash。

#3


2  

Your assignments are not creating arrays. You need arrayname=( values for array ) as the notation. Hence:

您的分配不是创建数组。您需要arrayname =(数组的值)作为表示法。因此:

files=( "$DOWNLOADDIRECTORY"/* )
files=( "${files[@]##*/}" )

The first line will give you all the names in the directory specified by $DOWNLOADDIRECTORY. The second carefully removes the directory prefix. I've used spaces after ( and before ) for clarity; the shell neither requires nor objects to them. I used double quotes around the variable name and expansions to keep things sane when name do contain spaces etc.

第一行将为您提供$ DOWNLOADDIRECTORY指定的目录中的所有名称。第二个小心地删除目录前缀。为了清晰起见,我在之后(和之前)使用了空格; shell既不需要也不反对它们。我在变量名称和扩展周围使用了双引号,以便在名称包含空格等时保持理智。

Although it isn't immediately obvious why you might do this, its advantage over many alternatives is that it preserves spaces etc in file names.

尽管为什么你可能会这样做并不是很明显,但它优于许多替代方案的优势在于它保留了文件名中的空格等。

#4


0  

You could just loop directly over the files:

你可以直接循环遍历文件:

for file in "$DOWNLOADDIRECTORY"/*; do
    file="${file##*/}" # or file=$(basename "$file")
    # MySQL stuff
done

Some quoting added in case of spaces in paths.

如果路径中有空格,则会添加一些引用。