【问题标题】:Execute a command with a Bash variable in it and store the result执行带有 Bash 变量的命令并存储结果
【发布时间】:2011-11-29 22:37:09
【问题描述】:

我不知道如何使用变量执行命令并获得结果。 我有很多 .h.c 文件,我需要将每个文件从 ISO-8859 转换为 UTF-8。

所以我做:

ls | grep "\.[ch]" | xargs myscript.sh

在我的脚本中,文件名在变量$1 中。现在我需要执行

iconv -f ISO-8859 -t UTF-8 $1

并存储此结果,因为iconv 打印到标准输出。

result=`iconv -f ISO-8859 -t UTF-8 $1`

echo $result

这似乎不起作用,因为它给了我一些不匹配而不是转换的$1

【问题讨论】:

  • “有些不匹配”?请引用您收到的确切错误消息。
  • 这不是错误。它是更多文件的混乱内容,然后只有 1 美元,我不明白。
  • ls | grep .. 发出的任何文件的文件名中有空格吗?那会把事情搞砸的。尝试在result=... 中更改为“$1”,但您可能需要想出一种方法来处理文件名中的空格。请使用 $1 的适当示例值和打乱内容的确切文本来编辑您的问题。祝你好运。
  • 如果您的文件小到可以捕获,那么您需要使用带有双引号的echo "$result" 来保留内部间距。如果没有双引号,您将获得单行输出,其中每个序列的一个或多个空格减少为一个空格。
  • 规范是 How do I set a variable to the output of a command in Bash?。尽管标题不明确,但它涵盖了(变量)输入到外部命令(在(Bash)变量中)的情况。

标签: bash shell unix


【解决方案1】:

如果您需要先对数据进行某种转换,您可以使用以下语法“捕获”输出:

result="$(iconv -f ISO-8859 -t UTF-8 $1)"

这里也有一个陷阱:如果您要存储大量数据,其中可能包含空格或其他麻烦的字符,请务必始终引用变量("$result" 而不是 $result)确保它被视为单个字符串。

【讨论】:

  • 这个$cmd $1 > $1 不仅会覆盖文件,它还会破坏首先。这是截断所有源文件的好方法。
  • 再次修复。伙计,我的壳生锈了。
  • 好的,-1 已删除 :) P.S. 这些大概是 C 源文件,所以是的,除非是提交混淆代码竞赛的,还有 肯定里面会有一些空格:)
  • 谢谢你,它给了我一些不匹配,因为我在回应它时没有引用 $result。
【解决方案2】:

我会这样做:

while read filename; 
do
    mv "$filename" "$filename.bck" && \
        iconv -f ISO-8859 -t UTF-8 "$filename.bck" > "$filename"
done < find -iname '*.[hc]'

这会即时创建备份并处理带有空格(不是换行符)的文件。

【讨论】:

  • 双引号处理字符串(文件名)中的换行符。
  • @JonathanLeffler:我认为在谈论换行符时,sehe 指的是while read。 IIRC,在 bash 中你可以做 while read -d $'\x00'.
  • 很公平 - 是的; while read filename 不会处理换行符。
【解决方案3】:

这是一个甚至可以处理换行符的解决方案:

find -name '*.[ch]' \
    -exec mv '{}' '{}.backup' \; \
    -exec iconv -f ISO-8859 -t UTF-8 '{}.backup' -o '{}' \;

通常,如果您要使用结果,从不解析文件名。我所知道的唯一理智的方法是

  1. 使用 shell glob,例如for file in ./*.[ch] ; do echo "$file" ; done。仅适用于一个目录。
  2. find-exec 结合使用
  3. 结合使用“find”和-print0(将文件名打印为\0 分隔的字符串)并使用输出来构建带有xargs -0 的命令行,可能还有一个帮助脚本。不过,这很麻烦。

另外,请确保您使用的相关文件名以./ 为前缀。调用mv -from -to 并不安全,但mv ./-from ./-to 是安全的,并且可以为所欲为。例如。通配符时,使用./*.c 而不是*.c

【讨论】:

    猜你喜欢
    • 2017-11-28
    • 2021-11-18
    • 1970-01-01
    • 2022-10-19
    • 2011-02-13
    • 1970-01-01
    • 2023-04-07
    • 2019-09-09
    • 2020-07-01
    相关资源
    最近更新 更多