问题
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