如何使用文件的行作为命令的参数?

时间:2010-11-19 18:04:36

标签: linux unix shell command-line command-line-arguments

说,我有一个文件foo.txt指定N个参数

arg1
arg2
...
argN

我需要传递给命令my_command

如何使用文件的行作为命令的参数?

11 个答案:

答案 0 :(得分:179)

如果你的shell是bash(以及其他),$(cat afile)的快捷方式是$(< afile),那么你就写了:

mycommand "$(< file.txt)"

在“命令替换”部分的bash手册页中记录。

同时,让你的命令从stdin读取,所以:mycommand < file.txt

答案 1 :(得分:34)

如前所述,您可以使用反引号或$(cat filename)

未提及的内容,我认为值得注意的是,您必须记住,shell会根据空格拆分该文件的内容,将它找到的每个“单词”作为参数发送给您的命令。虽然您可以将命令行参数括在引号中,以便它可以包含空格,转义序列等,但从文件中读取将不会执行相同的操作。例如,如果您的文件包含:

a "b c" d

你将获得的论点是:

a
"b
c"
d

如果要将每一行作为参数拉出,请使用while / read / do构造:

while read i ; do command_name $i ; done < filename

答案 2 :(得分:15)

你使用反引号来做到这一点:

echo World > file.txt
echo Hello `cat file.txt`

答案 3 :(得分:14)

command `< file`

会将文件内容传递给stdin上的命令,但会删除换行符,这意味着您无法单独遍历每一行。为此,您可以编写一个带有'for'循环的脚本:

for i in `cat input_file`; do some_command $i; done

答案 4 :(得分:6)

如果您希望以一种可行的方式执行此操作,该方法适用于每个可能的命令行参数(带空格的值,带换行符的值,带有文字引号字符的值,不可打印的值,带有glob字符的值等),变得更有趣了。


在给定一组参数的情况下写入文件:

printf '%s\0' "${arguments[@]}" >file

...替换为"argument one""argument two"等。视情况而定。


从该文件中读取并使用其内容(在bash,ksh93或其他带有数组的shell中):

declare -a args=()
while IFS='' read -r -d '' item; do
  args+=( "$item" )
done <file
run_your_command "${args[@]}"

从该文件读取并使用其内容(在没有数组的shell中;请注意,这将覆盖您的本地命令行参数列表,因此最好在函数内部完成,这样您就可以覆盖它函数的参数而不是全局列表):

set --
while IFS='' read -r -d '' item; do
  set -- "$@" "$item"
done <file
run_your_command "$@"

请注意,-d(允许使用不同的行尾分隔符)是非POSIX扩展,而没有数组的shell也可能不支持它。如果是这种情况,您可能需要使用非shell语言将NUL分隔的内容转换为eval - 安全形式:

quoted_list() {
  ## Works with either Python 2.x or 3.x
  python -c '
import sys, pipes, shlex
quote = pipes.quote if hasattr(pipes, "quote") else shlex.quote
print(" ".join([quote(s) for s in sys.stdin.read().split("\0")][:-1]))
  '
}

eval "set -- $(quoted_list <file)"
run_your_command "$@"

答案 5 :(得分:5)

这里是我如何将文件内容作为参数传递给命令:

./foo --bar "$(cat ./bar.txt)"

答案 6 :(得分:3)

在我的bash shell中,以下内容就像魅力一样:

cat input_file | xargs -I % sh -c 'command1 %; command2 %; command3 %;'

其中input_file是

arg1
arg2
arg3

很明显,这允许你用input_file中的每一行执行多个命令,这是我学到的一个不错的小技巧here

答案 7 :(得分:1)

如果您要做的只是打开包含内容的文件arguments.txt

arg1
arg2
argN

插入my_command arg1 arg2 argN,则只需使用xargs

xargs -a arguments.txt my_command

您可以在xargs调用中添加其他静态参数,例如xargs -a arguments.txt my_command staticArg,它将调用my_command staticArg arg1 arg2 argN

答案 8 :(得分:1)

我建议使用:

command $(echo $(tr '\n' ' ' < parameters.cfg))

只需修整末尾字符并将其替换为空格,然后将产生的字符串作为可能的单独参数用echo推送即可。

答案 9 :(得分:0)

几次编辑@Wesley Rice's answer之后,我认为我所做的更改太大了,无法继续更改他的答案,而不是自己编写答案。因此,我决定需要自己编写!

读取文件的每一行,并逐行对其进行操作,如下所示:

#!/bin/bash
input="/path/to/txt/file"
while IFS= read -r line
do
  echo "$line"
done < "$input"

这直接来自作者Vivek Gite,这里:https://www.cyberciti.biz/faq/unix-howto-read-line-by-line-from-file/。他获得了荣誉!

语法:在Bash Unix和Linux shell上逐行读取文件:
1. bash,ksh,zsh和所有其他shell逐行读取文件的语法如下:
2. while read -r line; do COMMAND; done < input.file
3.传递给read命令的-r选项可防止反斜杠转义被解释。
4.在读取命令前添加IFS=选项,以防止前导/后缀空白被修剪-
5. while IFS= read -r line; do COMMAND_on $line; done < input.file


现在我要回答这个已经关闭的问题:Is it possible to `git add` a list of files from a file?-这是我的答案:

请注意,FILES_STAGED是一个变量,它包含文件的绝对路径,该文件包含一堆行,其中每一行是我要对其进行git add的文件的相对路径。此代码段即将成为该项目中的“ eRCaGuy_dotfiles / useful_scripts / sync_git_repo_to_build_machine.sh” 文件的一部分,以使从一台PC(例如,我在其上编码的计算机)上正在开发的文件轻松同步)到另一台(例如:我要构建的功能更强大的计算机):https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles

while IFS= read -r line
do
    echo "  git add \"$line\""
    git add "$line" 
done < "$FILES_STAGED"

参考文献:

  1. 我在以下位置复制答案的位置:https://www.cyberciti.biz/faq/unix-howto-read-line-by-line-from-file/
  2. For循环语法:https://www.cyberciti.biz/faq/bash-for-loop/

相关:

  1. 如何逐行读取文件内容并对其进行git addIs it possible to `git add` a list of files from a file?

答案 10 :(得分:0)

似乎没有一个答案对我有用或太复杂。幸运的是,xargs 并不复杂(在 Ubuntu 20.04 上测试)。

这适用于文件中单独一行的每个 arg,正如 OP 所提到的,这也是我所需要的。

cat foo.txt | xargs my_command

需要注意的一点是它似乎不适用于别名命令。

如果命令接受包含在字符串中的多个参数,则接受的答案有效。在我使用 (Neo)Vim 的情况下,它不会并且所有参数都粘在一起。

xargs 可能并实际上为您提供了提供给命令的单独参数。