这个问题之前已经被问过,除了他们正在寻找两个日期之间的文本(包括或排除这些日期)。我更改了其中一个答案,以便它选择并包含第一个日期并转到但排除第二个日期(我认为/希望)。但是我不明白您在哪里提供了要应用此内容的文本文件?
set - date1 date2 "junk"
from="$1"
till="$2"
file="$3"
# Output lines between two parameter dates
# INCLUDING the first parameter date but not the second
awk -v from=$from -v till=$till '
($2 >= from) && ($2 < till) { print $0 ; next }
($2 >= till) { exit }' "$file"
自从发现了一个笨拙的解决方案后,我意识到还有另一个方面可以改进这一点,并防止我多次编写脚本行的细微更改。
目前的工作解决方案是:
awk '/^date_1_/,/^date_2_/ {print}' file.txt > file2.txt
grep -v "date_2_" file2.txt > file2tmp.txt
mv file2tmp.txt file2.txt
不过我希望它对每个新日期都这样做。例如,从Date_1_(包括date_1_)到Date_2_(但不包括Date_2_)选择文本,然后以同样的方式选择从Date_2_到3的文本,以同样的方式选择3到4(一直到1000)。有没有可以轻松扩展的解决方案?
输入文本文件示例(虽然实际文件最多为 1000,txt 文件中的下划线之间也没有空格,但我没有反勾来逃避斜体效果):
' > _ 1_ fe fi fo fum >_ 2_ beep bap bop >_ 3_ ti fi at at
示例输出:
创建的文本文件 1: > _ 1_ fe fi fo fum
创建的文本文件 2: >_ 2_ beep bap bop
创建的文本文件 3: >_ 3_ ti fi at at
答案1
如果我正确理解这个不断变化的问题的当前状态,您有一个具有任意行数的文件,分为由类似 to 标记的部分_1_
,_1000_
并且您希望将这些部分拆分为单独的文件。如果是这样,那么csplit
可以这样做:
csplit file.txt '/^_[0-9]\+_/' '{*}'
答案2
该awk
程序将通过一个命令完成您最初想做的事情:
awk '/^date_1_/,/^date_2_/ { if (prev) print prev ; prev=$0 }' file.txt > file2.txt
你测试了这个,它有效。然后,您扩展了问题,以便能够对作为参数对给出的一系列通用行标记进行操作。
您可以通过定义 2 个辅助函数来为此创建一个舒适的工作流程:
- 创建 awk 程序以通过进程替换输入
- 另一个运行 awk,并将参数传递给第一个助手:
代码:
fun1(){ while [ ! -z $1 ] && [ ! -z $2 ] ; do echo "
/^$1/,/^$2/ {if (\$0~/^$1/) prev=\"\";
if (prev) print prev; prev=\$0 }"; shift; shift ; done }
fun2(){ awk -f <(fun1 $@); }
# Example data, example ranges, but could be any string:
seq 1 13 | sed -e 's/.*/_&_/' | fun2 _2 _4 _9 _11
_2_
_3_
_9_
_10_
问题版本 3 的解决方案:
fun3(){ echo "/^$1/,/^$2/ {if (\$0~/^$1/) prev=\"\";
if (prev) print prev; prev=\$0 }"; }
fun4(){ ifile=$1; shift; while [ ! -z $1 ] && [ ! -z $2 ] ; do
awk -f <(fun3 $1 $2) $ifile > $1.txt ; shift; done }
# Create example data file:
seq 1 13 | sed -e 's/.*/_&_/' > inputData.txt
fun4 inputData.txt _2 _5 _8 _12
ls _*
_2.txt _5.txt _8.txt
答案3
我做了更多的阅读,并将一些东西拼凑在一起,这现在对我有用。
awk '/^date_1_/,/^date_2_/ {print}' file.txt > file2.txt
grep -v "date_2_" file2.txt > file2tmp.txt
mv file2tmp.txt file2.txt
但它仍然需要 2 个步骤和一个临时文件。