bash 如何在具有头尾操作的文件中使用管道?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36139574/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 14:23:24  来源:igfitidea点击:

How to use the pipe in a file with head-tail operation?

linuxbash

提问by Marko

    size=$(wc -l < "")
    if [ "$size" -gt 0 ]
    then
        tr "[:lower:]" "[:upper:]" <   > output
        for (( i=1; i <= "$size"; ++i ))
        do
            echo "Line " $i $(head -"$i" > output | tail -1 > output)
        done

Hi, guys! I have a problem with this little code. Everything works fine except the head-tail thing. What I wanna do is just displaying the line number "i" from a file. The results that I receive are just the last line ($size).

嗨,大家好!我对这个小代码有问题。除了头尾的东西,一切都很好。我想要做的只是显示文件中的行号“i”。我收到的结果只是最后一行($size)。

I think maybe it is something wrong with the input of tail. The head -"$i" doesn't go at the specified line. :( Any thoughts?

我想也许是tail的输入有问题。头 -"$i" 不在指定的行。:( 有什么想法吗?

Ohhhh... I just realised: As input for my tail i give the same input for head. The solution is to give to tail the result from head. How do I do that? :-/

Ohhhh...我刚刚意识到:作为我的尾巴的输入,我为头部提供了相同的输入。解决方案是从 head 给出尾部结果。我怎么做?:-/

采纳答案by Munir

You don't need to redirect to file outputfrom head. Otherwise, the pipe does not get any input at all. Also, use >>to append results otherwise you will just keep overwriting the file with the next iteration of the loop. But make sure to delete the output file before each new call to the script, else you will just keep appending to the output file infinitely.

你并不需要重定向到文件outputhead。否则,管道根本不会得到任何输入。此外,用于>>附加结果,否则您将在循环的下一次迭代中继续覆盖文件。但是请确保在每次新调用脚本之前删除输出文件,否则您只会无限地追加到输出文件中。

echo "Line " $i $(head -"$i" $infile | tail -1 >> output)

回答by chepner

Use readto fetch a line of input from the file.

用于read从文件中获取一行输入。

# Since `1` is always true, essentially count up forever
for ((i=1; 1; ++i)); do
    # break when a read fails to read a line
    IFS= read -r line || break
    echo "Line $i: $(tr [:lower:] [:upper:])"
done < "" > output

A more standard approach is to iterate over the file and maintain iexplicitly.

更标准的方法是迭代文件并i显式维护。

i=1
while IFS= read -r line; do
    echo "Line $i: $(tr [:lower:] [:upper:])"
    ((i++))
done < "" > output

回答by Marko

I made it. :D

我做到了。:D

The trick is to put the output of the head to another file that will be the input for tail, like that:

诀窍是将 head 的输出放在另一个文件中,该文件将作为 tail 的输入,如下所示:

echo "Line " $i $(head -"$i" < output >outputF | tail -1 < outputF)

Your questions made me think differently. Thank you!

你的问题让我有不同的想法。谢谢!

回答by karakfa

I think you're re-implementing cat -nwith prefix "Line ". If so, awkto the rescue!

我认为您正在cat -n使用前缀“Line”重新实现。如果是这样,awk救命!

awk '{print "Line "NR, tolower(##代码##)}'