gpt4 book ai didi

linux - 使用带有嵌入空格的参数(例如文件名)在 bash 脚本中调用命令

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:20:44 25 4
gpt4 key购买 nike

我正在尝试编写一个对音乐文件进行一些处理的 bash 脚本。这是到目前为止的脚本:

#!/bin/bash

SAVEIFS=$IFS
IFS=printf"\n\0"

find `pwd` -iname "*.mp3" -o -iname "*.flac" | while read f
do
echo "$f"
$arr=($(f))
exiftool "${arr[@]}"
done

IFS=$SAVEIFS

这失败了:

[johnd:/tmp/tunes] 2 $ ./test.sh 
./test.sh: line 9: syntax error near unexpected token `$(f)'
./test.sh: line 9: ` $arr=($(f))'
[johnd:/tmp/tunes] 2 $

我试过很多不同的咒语,但没有一个奏效。底线是我正在尝试调用命令 exiftool,该命令的参数之一是可能包含空格的文件名。上面我试图将文件名 $f 分配给一个数组并将该数组传递给 exiftool,但我在构建数组时遇到了问题。

直接的问题是,我该如何构造这个数组?但更深层次的问题是,如何从 bash 脚本中调用带有可能包含空格的参数的外部命令?

最佳答案

您实际上确实正确地使用了 call-with-possibly-space-containing-arguments 语法 ( program "${args[@]}" )。但是,存在几个问题。

首先,$(foo) 执行命令。如果你想要一个变量的值,使用 $foo${foo} .

其次,如果你想追加一些东西到一个数组,语法是array+=(value) (或者,如果这不起作用,array=("${array[@]}" value))。

第三,\0分隔文件名只要有可能。换行很好,但文件名可以包含换行。

第四,read接开关 -d , 可以与空字符串一起使用 ''指定 \0作为分隔符。这消除了乱用 IFS 的需要.

第五,管道进入while时要小心loops - 这会导致循环在子 shell 中执行,防止其内部的变量赋值在外部生效。然而,有一种方法可以解决这个问题 - 不要使用管道 ( command | while ... done ),而是使用进程替换 ( while ... done < <(command) )。

第六,注意你的进程替换 - 没有必要使用 $(pwd). 时作为命令的参数会做。 (或者,如果您真的必须有完整路径,请尝试引用 pwd 调用。)

tl;dr

修改后的脚本:

while read -r -d '' f; do
echo "$f" # For debugging?
arr+=("$f")
done < <(find . -iname "*.mp3" -o -iname "*.flac" -print0)
exiftool "${arr[@]}"

另一种方式

利用 find的全部功能:

find . -iname "*.mp3" -o -iname "*.flac" -exec exiftool {} +
# Much shorter!

编辑 1

所以你需要保存exiftool的输出,操纵它,然后复制东西?试试这个:

while read -r -d '' f; do
echo "$f" # For debugging?
arr+=("$f")
done < <(find . -iname "*.mp3" -o -iname "*.flac" -print0)
# Warning: somewhat misleading syntax highlighting ahead
newfilename="$(exiftool "${arr[@]}")"
newfilename="$(manipulate "$newfilename")"
cp -- "$some_old_filename" "$newfilename"

您可能需要更改最后一点 - 我从未使用过 exiftool ,所以我不确切地知道你在追求什么(或如何去做),但这应该是一个开始。

关于linux - 使用带有嵌入空格的参数(例如文件名)在 bash 脚本中调用命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16358580/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com