Bash错误修复:逐行读取文本文件并对其执行操作

时间:2018-11-01 17:34:33

标签: bash shell scripting sh

这是我的脚本的样子

#/bin/bash
touch input.txt
touch output.txt
seq -w 0 999 >>input.txt
input=$(cat input.txt)

for i in $input
  do
    if [ $(($i%2)) -eq 0 ]; then
      echo $i "even" >> output.txt
    else
      echo $i "odd" >> output.txt
   fi
 done

这是运行脚本并查看创建的output.txt文件的结果

000 even
001 odd
002 even
003 odd
004 even
005 odd
006 even
007 odd

我希望脚本对脚本的所有1000行执行此操作,但是我在第9行收到一条错误消息,提示

./tester.sh: line 9: 008: value too great for base (error token is "008")

我的最终目标是让脚本在一行上添加每个数字,然后判断该数字是偶数还是奇数,并针对文件的所有1000行输出到output.txt。

最终目标输出文件:

000 even
001 odd
002 even
003 odd
...
505 even
506 odd
507 even
508 odd
...
998 even
999 odd

从000一直到999

4 个答案:

答案 0 :(得分:1)

这是用于逐行读取文本文件并对其执行操作的基本代码...根据您的需要填充缺少的部分。

#!/bin/bash
{
  while read -r line; do
    if (( line % 2 == 0 )); then
      # ...
    else
      # ...
    fi
  done < input.txt
} > output.txt

您还可以使用<(cmd ...)表示法对输入文件进行预处理:

#!/bin/bash
{
  while read -r line; do
    ...
  done < <(arbitrary-cmd input.txt | another-cmd ... )
} > output.txt

这种形式看起来更好,但它会生成一个“子外壳”,并且如果有任何内容,while块中的代码将无法修改其外部定义的变量。

#!/bin/bash
{
  arbitrary-cmd input.txt | another-cmd ... | while read -r line; do
    ...
  done
} > output.txt

答案 1 :(得分:1)

使用seq作为seq并使用printf以您喜欢的格式打印号码。
Bash算术扩展将前导零的字符串解释为八进制数字。您可以通过在数字前加上10#(例如(( 10#$i % 2)))来强制数字排在第十。

for i in $input
  do
    if [ $(( 10#$i % 2)) -eq 0 ]; then
      echo $i "even" >> output.txt
    else
      echo $i "odd" >> output.txt
   fi
 done
  1. 请记住,算术扩展(( .. ))可以进行比较。 if (( 10#$i % 2 == 0 )); then很清楚。
  2. 在这种情况下,我发现printf "%03d" "$i"更清楚了。
  3. 不需要在>>之前触摸文件,应该自动创建文件(可以使用一些bash set -o选项将其关闭,但我还没有看到有人使用它。)
  4. input=$(cat ...); for i in $input太糟糕了。 Don't read lines with for
  5. 我不喜欢临时文件。
  6. How to read file line by line

您的脚本就是:

seq 0 999 | xargs -i sh -c 'printf "%03d " "$1"; (( $1 % 2 == 0 )) && echo even || echo odd;'  >>output.txt

如果您喜欢阅读的话:

seq 0 999 | while IFS= read -r num; do 
    printf "%03d " "$num"; 
    if (( num % 2 == 0 )); then 
        echo even
    else
        echo odd
    fi
done >>output.txt

或者,如果您必须要在input.txt文件中包含000\n001\n002\n and so on,那么就该tee了:

seq -w 0 999 | tee -a input.txt | while IFS= read -r num; do 
    echo -n "$num "
    if (( 10#$num % 2 == 0 )); then 
        echo even
    else
        echo odd
    fi
done >>output.txt

答案 2 :(得分:0)

您的脚本可能类似于

#!/bin/ksh
input=$(seq -w 0 999)
for i in $input
  do
    if [ $(($i%2)) -eq 0 ];then
      echo $i "even" >> output.txt
    else
      echo $i "odd" >> output.txt
    fi
  done

然后您的输出将类似于

000 even
001 odd
002 even
003 odd
004 even
005 odd
006 even
007 odd

然后,您可以grep“ even”或“ odd”并执行所需的操作,也可以直接在if / else语句中执行命令。

答案 3 :(得分:0)

这也可行:

#!/bin/bash
for x in `seq -w 0 999`; do
    if [ $((10#$x%2)) == 0 ]; then
        echo $x even
    else
        echo $x odd
    fi
done > output.txt