如何编写接受来自标准输入或文件的输入的脚本?

如何编写接受来自标准输入或文件的输入的脚本?

我有一个 awk 脚本的 bash 驱动程序,该脚本应该接受多个文件的cat text.txt | driver.sh输入。./driver.sh file1.txt file2.txt ... [filen.txt]我尝试过使用

   read var
   gawk -f awk_prac.awk $var

这仅适用于管道。我还尝试使用 for 循环来读取所有文件名,但这不适用于管道文本。任何意见都会受到赞赏。

答案1

两种解决方案,具体取决于您打算cat text.txt | driver.sh做什么(顺便说一句,最好写为driver.sh <text.txt)。

  1. 阅读数据text.txt
  2. 阅读路径名text.txt

如果该列表为空,您的“驱动程序”(实际上是包装器)脚本可以添加/dev/stdin到位置参数列表中:

#!/bin/sh

if [ "$#" -eq 0 ]; then
    set -- /dev/stdin
fi

gawk -f awk_prac.awk "$@"

如果不带任何参数调用包装器脚本,这将使awk脚本从标准输入流获取输入。

注意 的引用"$@"。这将扩展到每个位置参数(shell 脚本参数),单独引用,这意味着它将适用于名称中包含空格和/或 shell 通配符的文件名。

如果您的awk代码期望单身的每次调用文件,然后使用循环:

#!/bin/sh

if [ "$#" -eq 0 ]; then
    set -- /dev/stdin
fi

for pathname do
    gawk -f awk_prac.awk "$pathname"
done

如果您通过阅读标准输入意味着您想阅读路径名来自标准输入(而不是要处理的数据),那么您可能需要使用xargs(因为路径名的数量可能超过为调用awk脚本而生成的命令行的最大长度):

#!/bin/sh

if [ "$#" -eq 0 ]; then
    cat
else
    printf '%s\n' "$@"
fi | xargs -r gawk -f awk_prac.awk

如果没有给脚本提供参数,这会将路径名直接从标准输入(好吧,通过cat)传递到。xargs如果有参数,它们将打印为换行符分隔的列表以供xargs处理。再次强调,引用"$@"是必不可少的。

如果复合语句没有为其提供数据,则该-r选项将xargs停止实用程序的运行。这是一个非标准选项,请检查您的手册。gawkifxargs

如果您的awk代码期望单身的每次调用都会创建一个文件,然后xargs-L 1.

答案2

1 从文件输入

您可以编写一个小脚本来读取文件名以从文件中进行操作。

示例文件

$ cat /tmp/files.txt
one.txt
two.txt
three.txt

脚本

while read -r fileName; do 
    gawk -f awk_prac.awk $fileName; 
done < /tmp/files.txt

输出:

one.txt
two.txt
three.txt

2 从标准输入输入

类似地,您也可以从 stdin 获取输入。您可以每行提供一个文件名或在一行上提供所有文件名,并相应地编写脚本。

答案3

脚本文件驱动程序.sh

#!/usr/bin/bash

for argument do
gawk -f awk_prac.awk "$argument";
done

执行(您可以提供多个文件):

$./driver.sh file1.txt file2.txt ... [filen.txt]

如果文件名给出标准输入,可以使用 for 循环来运行每个文件:

while read -p "Enter File name : " file
do
gawk -f awk_prac.awk $file
echo "Press Ctrl+C to quit"
done

执行:只是

$./driver.sh

相关内容