如何将文本文件的每一行解析为命令的参数?

如何将文本文件的每一行解析为命令的参数?

我正在编写一个脚本,该脚本将.txt文件名作为参数,逐行读取文件,并将每一行传递给命令。例如,它运行command --option "LINE 1"、 thencommand --option "LINE 2"等。命令的输出被写入另一个文件。我该如何去做呢?我不知道从哪里开始。

答案1

另一种选择是xargs

使用 GNU xargs

xargs -a file -I{} -d'\n' command --option {} other args

{}是文本行的占位符。

其他xargs通常没有-a, -d,但有些有-0NUL 分隔输入。有了这些,您可以执行以下操作:

< file tr '\n' '\0' | xargs -0 -I{} command --option {} other args

在符合 Unix 的系统上(-I在 POSIX 中是可选的,仅适用于符合 UNIX 的系统),您需要预处理输入引用预期格式的行xargs

< file sed 's/"/"\\""/g;s/.*/"&"/' |
  xargs -E '' -I{} command --option {} other args

但请注意,某些xargs实现对参数的最大大小有非常低的限制(例如,Solaris 上为 255,这是 Unix 规范允许的最小值)。

答案2

使用while read循环:

: > another_file  ## Truncate file.

while IFS= read -r line; do
    command --option "$line" >> another_file
done < file

另一种是按块重定向输出:

while IFS= read -r line; do
    command --option "$line"
done < file > another_file

最后是打开文件:

exec 4> another_file

while IFS= read -r line; do
    command --option "$line" >&4
    echo xyz  ## Another optional command that sends output to stdout.
done < file

如果其中一个命令读取输入,最好使用另一个 fd 进行输入,这样命令就不会吃掉它(这里假设kshzshbashfor -u 3,使用<&3可移植的方式代替):

while IFS= read -ru 3 line; do
    ...
done 3< file

最后要接受参数,你可以这样做:

#!/bin/bash

file=$1
another_file=$2

exec 4> "$another_file"

while IFS= read -ru 3 line; do
    command --option "$line" >&4
done 3< "$file"

哪一个可以运行为:

bash script.sh file another_file

额外的想法。与bash, 使用readarray:

readarray -t lines < "$file"

for line in "${lines[@]}"; do
    ...
done

注意:IFS=如果您不介意删除行值的前导空格和尾随空格,则可以省略。

答案3

准确地回答这个问题:

#!/bin/bash

# xargs -n param sets how many lines from the input to send to the command

# Call command once per line
[[ -f $1 ]] && cat $1 | xargs -n1 command --option

# Call command with 2 lines as args, such as an openvpn password file
# [[ -f $1 ]] && cat $1 | xargs -n2 command --option

# Call command with all lines as args
# [[ -f $1 ]] && cat $1 | xargs command --option

答案4

    sed "s/'/'\\\\''/g;s/.*/\$* '&'/" <<\FILE |\
    sh -s -- command echo --option
all of the{&}se li$n\es 'are safely shell
quoted and handed to command as its last argument
following --option, and, here, before that echo
FILE

输出

--option all of the{&}se li$n\es 'are safely shell
--option quoted and handed to command as its last argument
--option following --option, and, here, before that echo

相关内容