1
varrr=0

while read line
do
    if [ $line -gt 500 -a $line -le 600 ]; then    # for lines 501-600
        echo $line >> 'file_out_${varrr}.ubi'
    fi
done << 'file_in_${varrr}.ubi'

file_in_${varrr}.ubi是一个大约 1000 行的文本文件。我想将第 501-600 行打印到新文件中。

运行此代码会在我的 Ubuntu 终端上留下>一个新行符号,就好像我需要键入另一个命令来完成循环一样。我无法弄清楚这个循环有什么问题。好像已经完成了。看看我犯了什么错误?谢谢。

4

3 回答 3

1

如果您只想打印从 501 到 600 的行,为什么不使用以下内容?

awk 'NR>=501 && NR<=600' file_in > file_out

awk 'NR==n' myfile打印n文件的行myfile。然后,您可以使用我上面写的范围。

于 2013-09-13T09:59:30.157 回答
1

您可以简单地使用 sed。它是最简单的工具,比while带有测试的循环更干净、更快捷。

varrr=0
sed -n 501,600p "file_in_${varrr}.ubi" >> "file_out_${varrr}.ubi"

或者

varrr=0
sed -n 501,600p "file_in_${varrr}.ubi" > "file_out_${varrr}.ubi"

如果要覆盖现有数据。

顺便说一句,循环中的错误是因为您没有使用计数器而是通过行本身来比较行号。

varrr=0
counter=0
while read line; do
    (( ++counter ))
    [[ counter -gt 500 && counter -le 600 ]] && echo "$line"
done < "file_in_${varrr}.ubi" > "file_out_${varrr}.ubi"

值得注意的是,您需要不使用<输入<<并将变量放在双引号而不是单引号周围。

于 2013-09-13T10:23:39.467 回答
1

我只会回答您的具体问题:这是因为您使用了 heredoc<<符号,而不是 redirection <。你的最后一行应该是:

done < 'file_in_${varrr}.ubi'

(观察 <)。

但是你会意识到你有一些引用问题。所以,你的最后一行应该是:

done < "file_in_${varrr}.ubi"

(注意双引号 ")。

同样,请注意第 6 行中的引用。您应该改为:

echo "$line" >> "file_out_${varrr}.ubi"

双引号 "代表file_out_${varrr}.ubi)。

但是,这不会像你期望的那样表现......也许会这样做:

varrr=0
linenb=0
while IFS= read -r line; do
    ((++linenb))
    if ((linenb>500 && linenb<=600)); then    # for lines 501-600
        echo "$line" >> "file_out_${varrr}.ubi"
    fi
done < "file_in_${varrr}.ubi"

希望这可以帮助!

于 2013-09-13T10:27:16.617 回答