我有一个 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
)。
- 阅读数据从
text.txt
。 - 阅读路径名从
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
停止实用程序的运行。这是一个非标准选项,请检查您的手册。gawk
if
xargs
如果您的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