逐行读取文件并在shell脚本中的同一循环中分配两行

时间:2017-02-04 06:57:36

标签: bash shell

我有一个超过1,000行的.txt文件,它喜欢这样:

Y1
Y2
Y3
...

我想在脚本中读取它们并生成Makefile。 我想我应该使用循环,这可能会得到:

$file_Y2(as a target): $file_Y1(as a prerequisites)
command
$file_Y3(as a target): $file_Y2(as a prerequisites)
command
...

但在使用read -r line的循环中,我可以执行诸如将Y1($line)分配给$file_Y1之类的内容,但不知道如何分配Y2到同一循环中的$file_Y2(下一行)。

有什么建议吗?

4 个答案:

答案 0 :(得分:2)

您可以将数据映射到数组中,然后遍历数组。

mapfile -t -O1 lines < file
for ((i=1;i<${#lines[@]};i++));do
    echo "target file ${lines[i+1]} - depends on ${lines[i]}"
done

答案 1 :(得分:0)

以下样本怎么样?

awk '{ar[NR]=$0} END {for (i in ar) {if (i>1) {{print "$file_"ar[i]"(as a target): $file_"ar[i-1]"(as a prerequisites)"}{print "command"}}}}' file.txt

输入:

Y1
Y2
Y3
Y4

输出:

$file_Y2(as a target): $file_Y1(as a prerequisites)
command
$file_Y3(as a target): $file_Y2(as a prerequisites)
command
$file_Y4(as a target): $file_Y3(as a prerequisites)
command

答案 2 :(得分:0)

你可以这样做:

#!/bin/bash
skip=yes
while read line; do
  if [ $skip = yes ]; then 
    oldline=$line
  else 
    echo "\$file_$line(as target): \$file_$oldline(as prerequisite)"
    oldline=$line
  fi
  skip=no
done < tmp.txt

根据您的输入,输出为:

$file_Y2(as target): $file_Y1(as prerequisite)
$file_Y3(as target): $file_Y2(as prerequisite)
$file_Y4(as target): $file_Y3(as prerequisite)

据我了解,技巧是你需要两个输入行来生成一个新的输出行。因此,您需要两个变量 - 来自输入的行,保存在$行中,另一行保存在$ oldline中。在你的情况下,你需要一行,而前一个,所以$ oldline只记得前一行。没有什么能阻止你做别的事情,甚至在每一行生成之后都添加“一些命令”。

答案 3 :(得分:0)

您希望复制输入的大部分内容。使用paste,您可以组合两个文件的相应行。使用<(),您可以将命令的输出作为输入文件,因此我们可以使用sed删除第一行或最后一行:

paste <(sed '1d' input.txt) <(sed '$d' input.txt)

现在您想使用paste输出来写行。

printf "\$file_%s(as a target): \$file_%s(as a prerequisites)\ncommand\n" \
   $(paste <(sed '1d' input.txt) <(sed '$d' input.txt))

(请注意,在第一行末尾的\后面不应有空格或制表符。)