如何从 bash 中的文件循环打印 2 列
How do I print 2 columns with looping from a file in bash
我有以下 output.txt
它只包含 2 列来演示:
Test1 Test1-IS-OK
Test2 Test2-IS-NOT
Test3 Test3-IS-OK
Test4 Test4-IS-OK
Test5 Test5-IS-NOT
然后我的bash脚本有如下代码:
#!/bin/bash
output="output.txt"
a=$(awk '{ print }' $output)
b=$(awk '{ print }' $output)
while IFS=" " read -r $a $b
do
echo "LOG: $a and $b"
done < "$output"
我收到以下错误:
./test.sh: line 13: read: `Test1-IS-OK': not a valid identifier
我需要这样的输出
LOG: Test1 and Test1-IS-OK
LOG: Test2 and Test2-IS-NOT
LOG: Test3 and Test3-IS-OK
LOG: Test4 and Test4-IS-OK
LOG: Test5 and Test5-IS-NOT
但是代码不起作用。从文件中循环这两列的最佳方法是什么?有没有更简单的方法?
最好避免 bash 并完全在 awk 中执行此操作。在 awk 中它很简单:
awk '{print "LOG:", , "and", }' file
LOG: Test1 and Test1-IS-OK
LOG: Test2 and Test2-IS-NOT
LOG: Test3 and Test3-IS-OK
LOG: Test4 and Test4-IS-OK
LOG: Test5 and Test5-IS-NOT
请考虑将 awk
解析转移到它所属的循环中:
#!/bin/bash
output="output.txt"
while read -r line
do
a=$(echo "${line}" | awk '{print }')
b=$(echo "${line}" | awk '{print }')
echo "LOG: $a and $b"
done < "$output"
根据@EdMorton 的好建议编辑
你的代码有什么问题?
a=$(awk '{ print }' $output)
使用 echo "a=${a}"
你会看到,a 充满了所有行的输出。您正在尝试查找要在 $a
.
之后调用的函数
while IFS=" " read -r $a $b
现在您正在尝试调用“函数”a 和 b。代码将在读取输入文件之前替换变量的值。当 a 填充“Test1 Test2”时,代码将尝试填充字段 $Test1
和 $Test2
.
当你只想改变输出,而不想将变量传递给另一个语句时,你可以使用awk
,或者
sed -E 's/([^ ]*) ([^ ]*).*/LOG: and /' $output
# or
printf 'LOG: %s and %s\n' $(<$output)
在你的情况下,你可以read
读取两个参数:
while read -r a b
do
echo "LOG: $a and $b"
done < "$output"
使用这个 Perl one-liner:
perl -lane 'print "LOG: $F[0] and $F[1]";' output.txt > new.txt
Perl one-liner 使用这些命令行标志:
-e
:告诉 Perl 查找代码 in-line,而不是在文件中。
-n
:一次循环输入一行,默认分配给 $_
。
-l
: 在执行代码 in-line 之前去除输入行分隔符(默认情况下在 *NIX 上为 "\n"
),并在打印时附加它。
-a
: 在空格或 -F
选项中指定的正则表达式上将 $_
拆分为数组 @F
。
另请参见:
perldoc perlrun
: how to execute the Perl interpreter: command line switches
我有以下 output.txt
它只包含 2 列来演示:
Test1 Test1-IS-OK
Test2 Test2-IS-NOT
Test3 Test3-IS-OK
Test4 Test4-IS-OK
Test5 Test5-IS-NOT
然后我的bash脚本有如下代码:
#!/bin/bash
output="output.txt"
a=$(awk '{ print }' $output)
b=$(awk '{ print }' $output)
while IFS=" " read -r $a $b
do
echo "LOG: $a and $b"
done < "$output"
我收到以下错误:
./test.sh: line 13: read: `Test1-IS-OK': not a valid identifier
我需要这样的输出
LOG: Test1 and Test1-IS-OK
LOG: Test2 and Test2-IS-NOT
LOG: Test3 and Test3-IS-OK
LOG: Test4 and Test4-IS-OK
LOG: Test5 and Test5-IS-NOT
但是代码不起作用。从文件中循环这两列的最佳方法是什么?有没有更简单的方法?
最好避免 bash 并完全在 awk 中执行此操作。在 awk 中它很简单:
awk '{print "LOG:", , "and", }' file
LOG: Test1 and Test1-IS-OK
LOG: Test2 and Test2-IS-NOT
LOG: Test3 and Test3-IS-OK
LOG: Test4 and Test4-IS-OK
LOG: Test5 and Test5-IS-NOT
请考虑将 awk
解析转移到它所属的循环中:
#!/bin/bash
output="output.txt"
while read -r line
do
a=$(echo "${line}" | awk '{print }')
b=$(echo "${line}" | awk '{print }')
echo "LOG: $a and $b"
done < "$output"
根据@EdMorton 的好建议编辑
你的代码有什么问题?
a=$(awk '{ print }' $output)
使用 echo "a=${a}"
你会看到,a 充满了所有行的输出。您正在尝试查找要在 $a
.
while IFS=" " read -r $a $b
现在您正在尝试调用“函数”a 和 b。代码将在读取输入文件之前替换变量的值。当 a 填充“Test1 Test2”时,代码将尝试填充字段 $Test1
和 $Test2
.
当你只想改变输出,而不想将变量传递给另一个语句时,你可以使用awk
,或者
sed -E 's/([^ ]*) ([^ ]*).*/LOG: and /' $output
# or
printf 'LOG: %s and %s\n' $(<$output)
在你的情况下,你可以read
读取两个参数:
while read -r a b
do
echo "LOG: $a and $b"
done < "$output"
使用这个 Perl one-liner:
perl -lane 'print "LOG: $F[0] and $F[1]";' output.txt > new.txt
Perl one-liner 使用这些命令行标志:
-e
:告诉 Perl 查找代码 in-line,而不是在文件中。
-n
:一次循环输入一行,默认分配给 $_
。
-l
: 在执行代码 in-line 之前去除输入行分隔符(默认情况下在 *NIX 上为 "\n"
),并在打印时附加它。
-a
: 在空格或 -F
选项中指定的正则表达式上将 $_
拆分为数组 @F
。
另请参见:
perldoc perlrun
: how to execute the Perl interpreter: command line switches