BASH 脚本 - 使用变量执行命令并存储结果

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8318747/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 21:15:58  来源:igfitidea点击:

BASH script - execute command with variable and store result

bashshellunix

提问by designerrr

I don't know how execute a command with variable and get result of this. I have many .hand .cfiles and I need convert each from ISO-8859 to UTF-8.

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

So I make:

所以我做:

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

And in my script in variable $1is the filename. Now I need to perform

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

iconv -f ISO-8859 -t UTF-8 

and store result of this, because iconvprint to stdout.

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

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

echo $result 

This seems to be not working, because it give me some mismatch instead of converted $1.

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

采纳答案by Michael

If you need to do some kind of transformation on the data first, you can "capture" output with the following syntax:

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

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

There is a gotcha here as well: if you are going to be storing large amounts of data with potential whitespace or other meddlesome characters in it, be sure to always quote the variable ("$result"instead of $result) to ensure it gets treated as a single string.

这里也有一个问题:如果您要存储大量带有潜在空格或其他麻烦字符的数据,请务必始终引用变量("$result"而不是$result)以确保将其视为单个字符串。

回答by Jo So

Here is a solution that even handles newlines:

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

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

Generally, NEVER parse filenames if you are going to use the results. The only sane ways I know of are

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

  1. Use shell globs, e.g. for file in ./*.[ch] ; do echo "$file" ; done. Only works for one directory.
  2. Use find in combination with -exec
  3. Use find in combination with -print0 (which prints the filenames as \0-separated strings) and use the output to build commandlines with xargs -0and probably a helper script. This is quite cumbersome, though.
  1. 使用 shell glob,例如for file in ./*.[ch] ; do echo "$file" ; done. 仅适用于一个目录。
  2. 将 find 与 -exec 结合使用
  3. 将 find 与 -print0 结合使用(将文件名打印为以 \0 分隔的字符串)并使用输出来构建命令行,xargs -0并且可能是一个帮助脚本。不过,这相当麻烦。

Also, make sure that relative filenames you use are prefixed with ./. Calling mv -from -toisn't safe, but mv ./-from ./-tois, and does what you want. E.g. when globbing, go with ./*.crather than *.c.

此外,请确保您使用的相关文件名以./. 打电话mv -from -to不安全,但mv ./-from ./-to可以,而且可以做你想做的事。例如,在通配时,使用 with./*.c而不是*.c

回答by sehe

I'd do as such:

我会这样做:

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

This creates backups on the fly and also handles files with whitespace (not newline characters).

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