Bash split file on double newline

痞子三分冷 提交于 2021-02-10 07:14:41

问题


I have some files with content that change from file to file. Each file have 2 sections of lines separated by a blank line. I never know how many lines or characters there are in either section.

The file can look something like this.

This is a file
with some text

and some more text

This code only gives the first line from each section.

awk 'BEGIN {RS="\n\n"; FS="\n";} {print $1 }' file

I need each section split up to work with.


回答1:


Prints first part: sed '/^$/q' test.txt

Prints second part: sed '1,/^$/d' test.txt




回答2:


Set RS to a null/blank value to get awk to operate on sequences of blank lines.

From the POSIX specification for awk:

RS

The first character of the string value of RS shall be the input record separator; a by default. If RS contains more than one character, the results are unspecified. If RS is null, then records are separated by sequences consisting of a plus one or more blank lines, leading or trailing blank lines shall not result in empty records at the beginning or end of the input, and a shall always be a field separator, no matter what the value of FS is.




回答3:


Since this is tagged bash, might as well have a native-bash solution.

sections=( )
current_section=
while REPLY=; IFS= read -r || [[ $REPLY ]]; do
  if [[ $REPLY ]]; then
    # preserve newlines within the sections
    if [[ $current_section ]]; then
      current_section+=$'\n'"$REPLY"
    else
      current_section+=$REPLY
    fi
  else
    sections+=( "$current_section" )
    current_section=
  fi
done <file

This will put your file's individual sections into a bash array called sections.

You can print the contents of that array like so:

printf -- '---\n%s\n---\n' "${sections[@]}"

...or iterate over it to do as you please:

for section in "${sections[@]}"; do
  : do something with "$section" here
done



回答4:


Supposing that there are precisely two parts, this very simple Perl trick will print the the standard output until it encounters an empty line, and then the remainder to error;

 perl -ne 'if (1../^$/) { print STDOUT } else { print STDERR }'

e.g. cat tmp0 | perl -ne 'if (1../^$/) { print STDOUT } else { print STDERR }' > tmp1 2> tmp2

tmp1:

This is a file
with some text

tmp2:

and some more text



回答5:


IFS=";"
sections=($(awk -v RS= '{print $0 ";"}' filename))

IFS=; sets the internal field separator from space(default) to a semicolon

$(awk -v RS= '{print $0 ";"}' filename) it gives all the sections separated by ;.

sections=(awk_output_here) it splits the awk output based on the IFS and converts each section into the array's element. Hence, sections contain each section split based on the double new line.



来源:https://stackoverflow.com/questions/30744480/bash-split-file-on-double-newline

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!