Iterate over lines instead of words in a for loop of shell script

前端 未结 3 1779
感情败类
感情败类 2020-12-24 05:29

Following is the shell script to read all the DSF present in the box. But since the line is having spaces, it is displaying them in different lines. For those of you who don

3条回答
  •  忘掉有多难
    2020-12-24 06:00

    Using for

    for l in $() performs word splitting based on IFS:

    $ for l in $(printf %b 'a b\nc'); do echo "$l"; done
    a
    b
    c
    $ IFS=$'\n'; for l in $(printf %b 'a b\nc'); do echo "$l"; done
    a b
    c
    

    IFS doesn't have to be set back if it is not used later.

    for l in $() also performs pathname expansion:

    $ printf %b 'a\n*\n' > file.txt
    $ IFS=$'\n'
    $ for l in $(

    If IFS=$'\n', linefeeds are stripped and collapsed:

    $ printf %b '\n\na\n\nb\n\n' > file.txt
    $ IFS=$'\n'; for l in $(

    $(cat file.txt) (or $() also reads the whole file to memory.

    Using read

    Without -r backslashes are used for line continuation and removed before other characters:

    $ cat file.txt
    \1\\2\
    3
    $ cat file.txt | while read l; do echo "$l"; done
    1\23
    $ cat file.txt | while read -r l; do echo "$l"; done
    \1\\2\
    3
    

    Characters in IFS are stripped from the start and end of lines but not collapsed:

    $ printf %b '1  2 \n\t3\n' | while read -r l; do echo "$l"; done
    1  2
    3
    $ printf %b ' 1  2 \n\t3\n' | while IFS= read -r l; do echo "$l"; done
     1  2 
        3
    

    If the last line doesn't end with a newline, read assigns l to it but exits before the body of the loop:

    $ printf 'x\ny' | while read l; do echo $l; done
    x
    $ printf 'x\ny' | while read l || [[ $l ]]; do echo $l; done
    x
    y
    

    If a while loop is in a pipeline, it is also in a subshell, so variables are not visible outside it:

    $ x=0; seq 3 | while read l; do let x+=l; done; echo $x
    0
    $ x=0; while read l; do let x+=l; done < <(seq 3); echo $x
    6
    $ x=0; x=8 | x=9; echo $x
    0
    

提交回复
热议问题