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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4227994/
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-08-03 23:53:08  来源:igfitidea点击:

How do I use the lines of a file as arguments of a command?

linuxunixshellcommand-linecommand-line-arguments

提问by Yoo

Say, I have a file foo.txtspecifying Narguments

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

arg1
arg2
...
argN

which I need to pass to the command my_command

我需要传递给命令 my_command

How do I use the lines of a file as arguments of a command?

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

采纳答案by glenn Hymanman

If your shell is bash (amongst others), a shortcut for $(cat afile)is $(< afile), so you'd write:

如果你的shell是bash(其中包括),对于一个快捷方式$(cat afile)$(< afile),所以你会写:

mycommand "$(< file.txt)"

Documented in the bash man page in the 'Command Substitution' section.

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

Alterately, have your command read from stdin, so: mycommand < file.txt

或者,从标准输入读取您的命令,因此: mycommand < file.txt

回答by Tommy Lacroix

You do that using backticks:

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

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

回答by Wesley Rice

command `< file`

will pass file contents to the command on stdin, but will strip newlines, meaning you couldn't iterate over each line individually. For that you could write a script with a 'for' loop:

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

for line in `cat input_file`; do some_command "$line"; done

Or (the multi-line variant):

或(多行变体):

for line in `cat input_file`
do
    some_command "$line"
done

Or (multi-line variant with $()instead of ``):

或(多行变体$()而不是``):

for line in $(cat input_file)
do
    some_command "$line"
done

References:

参考:

  1. For loop syntax: https://www.cyberciti.biz/faq/bash-for-loop/
  1. For 循环语法:https: //www.cyberciti.biz/faq/bash-for-loop/

回答by Will

As already mentioned, you can use the backticks or $(cat filename).

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

What was not mentioned, and I think is important to note, is that you must remember that the shell will break apart the contents of that file according to whitespace, giving each "word" it finds to your command as an argument. And while you may be able to enclose a command-line argument in quotes so that it can contain whitespace, escape sequences, etc., reading from the file will not do the same thing. For example, if your file contains:

没有提到的,我认为重要的是要注意的是,您必须记住,shell 将根据空格拆分该文件的内容,将它找到的每个“单词”作为参数提供给您的命令。虽然您可以将命令行参数括在引号中,以便它可以包含空格、转义序列等,但从文件中读取不会做同样的事情。例如,如果您的文件包含:

a "b c" d

the arguments you will get are:

你会得到的论点是:

a
"b
c"
d

If you want to pull each line as an argument, use the while/read/do construct:

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

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

回答by honkaboy

In my bash shell the following worked like a charm:

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

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

where input_file is

input_file 在哪里

arg1
arg2
arg3

As evident, this allows you to execute multiple commands with each line from input_file, a nice little trick I learned here.

很明显,这允许您对 input_file 中的每一行执行多个命令,这是我在这里学到的一个不错的小技巧。

回答by Charles Duffy

If you want to do this in a robust way that works for every possible command line argument (values with spaces, values with newlines, values with literal quote characters, non-printable values, values with glob characters, etc), it gets a bit more interesting.

如果您想以适用于每个可能的命令行参数(带空格的值、带换行符的值、带文字引号的值、不可打印的值、带 glob 字符的值等)的稳健方式执行此操作,它会有点更有意思的。



To write to a file, given an array of arguments:

要写入文件,给定一组参数:

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

...replace with "argument one", "argument two", etc. as appropriate.

...替换为"argument one","argument two"等。



To read from that file and use its contents (in bash, ksh93, or another recent shell with arrays):

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

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


To read from that file and use its contents (in a shell without arrays; note that this will overwrite your local command-line argument list, and is thus best done inside of a function, such that you're overwriting the function's arguments and not the global list):

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

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("
./foo --bar "$(cat ./bar.txt)"
")][:-1])) ' } eval "set -- $(quoted_list <file)" run_your_command "$@"

Note that -d(allowing a different end-of-line delimiter to be used) is a non-POSIX extension, and a shell without arrays may also not support it. Should that be the case, you may need to use a non-shell language to transform the NUL-delimited content into an eval-safe form:

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

arg1
arg2
argN

回答by chovy

Here's how I pass contents of a file as an argument to a command:

下面是我如何将文件的内容作为参数传递给命令:

xargs -a arguments.txt my_command

回答by Cobra_Fast

If all you need to do is to turn file arguments.txtwith contents

如果您需要做的就是将文件转换arguments.txt为内容

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

into my_command arg1 arg2 argNthen you can simply use xargs:

进入my_command arg1 arg2 argN然后你可以简单地使用xargs

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

You can put additional static arguments in the xargscall, like xargs -a arguments.txt my_command staticArgwhich will call my_command staticArg arg1 arg2 argN

您可以在xargs调用中添加额外的静态参数,例如xargs -a arguments.txt my_command staticArgwhich will callmy_command staticArg arg1 arg2 argN

回答by Gabriel Staples

After editing @Wesley Rice's answera couple times, I decided my changes were just getting too big to continue changing his answer instead of writing my own. So, I decided I need to write my own!

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

Read each line of a file in and operate on it line-by-line like this:

读取文件的每一行并像这样逐行操作:

##代码##

This comes directly from author Vivek Gite here: https://www.cyberciti.biz/faq/unix-howto-read-line-by-line-from-file/. He gets the credit!

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

Syntax: Read file line by line on a Bash Unix & Linux shell:
1. The syntax is as follows for bash, ksh, zsh, and all other shells to read a file line by line
2. while read -r line; do COMMAND; done < input.file
3. The -roption passed to read command prevents backslash escapes from being interpreted.
4. Add IFS=option before read command to prevent leading/trailing whitespace from being trimmed -
5. while IFS= read -r line; do COMMAND_on $line; done < input.file

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



And now to answer this now-closed question which I also had: Is it possible to `git add` a list of files from a file?- here's my answer:

现在来回答我也遇到的这个现已结束的问题:是否可以从文件中`git add`一个文件列表?- 这是我的答案:

Note that FILES_STAGEDis a variable containing the absolute path to a file which contains a bunch of lines where each line is a relative path to a file I'd like to do git addon. This code snippet is about to become part of the "eRCaGuy_dotfiles/useful_scripts/sync_git_repo_to_build_machine.sh"file in this project, to enable easy syncing of files in development from one PC (ex: a computer I code on) to another (ex: a more powerful computer I build on): https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles.

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

##代码##

References:

参考:

  1. Where I copied my answer from: https://www.cyberciti.biz/faq/unix-howto-read-line-by-line-from-file/
  2. For loop syntax: https://www.cyberciti.biz/faq/bash-for-loop/
  1. 我从哪里复制了我的答案:https: //www.cyberciti.biz/faq/unix-howto-read-line-by-line-from-file/
  2. For 循环语法:https: //www.cyberciti.biz/faq/bash-for-loop/

Related:

有关的:

  1. How to read contents of file line-by-line and do git addon it: Is it possible to `git add` a list of files from a file?
  1. 如何逐行读取文件内容并git add对其进行操作:是否可以从文件中`git add`一个文件列表?