根据分隔符和最大长度将长字符串拆分为较小的字符串?

时间:2016-05-02 03:06:14

标签: string bash awk sed

我在bash脚本中有很长的字符串,我想分解为子字符串。分隔符是&&或||而且(困难的部分)每个子字符串不能超过70个字符。

例如,像这样的长单字符串:

(Dfa_and_Cfa && Second_Up_or_Down && Third_Down_or_Up_or_Positive) || (First_Up_or_Down) && Third_Down_or_Up && Dfa_and_Cfa && Third_Down_or_Up && Fourth_Up_or_Down

分手:

(Dfa_and_Cfa && Second_Up_or_Down && Third_Down_or_Up_or_Positive) ||
(First_Up_or_Down) && Third_Down_or_Up && Dfa_and_Cfa &&
Third_Down_or_Up && Fourth_Up_or_Down

到目前为止,我一直在使用awk:

  • 获取最多字段数

    max_fields=$(echo $long_string | awk -F'[&][&]|[|][|]' '{ print NF }')

  • 计算每个字段的长度

  • 如果长度小于70,则打印长度为70
  • 的所有字段
  • 继续留下剩下的字段

但是用awk我松了我的&&和||符号。所以我最终打印出来了:

Dfa_and_Cfa Second_Up_or_Down Third_Down_or_Up_or_Positive

我不认为这是正确的做法。有帮助吗?

4 个答案:

答案 0 :(得分:3)

为什么不尝试使用折叠?

module.exports = function(mongoose) {
 var Schema = mongoose.Schema;  

  /* bloodGroup Schema */
  var bloodGroupSchema = new Schema({
   name: { type: String, required: true }
  });
}

答案 1 :(得分:3)

使用GNU awk为第4个arg to split():

$ cat tst.awk
{
    prev = ""
    nf = split($0,f,/\s*(&&|\|\|)\s*/,s)
    for (i=1;i<=nf;i++) {
        curr = f[i] s[i]
        if ( length(prev curr) > 70 ) {
            print prev
        }
        else {
            curr = prev curr
        }
        prev = curr
    }
    print curr
}

$ awk -f tst.awk file
(Dfa_and_Cfa && Second_Up_or_Down && Third_Down_or_Up_or_Positive) ||
(First_Up_or_Down) && Third_Down_or_Up && Dfa_and_Cfa &&
Third_Down_or_Up && Fourth_Up_or_Down

答案 2 :(得分:1)

尝试一下:

years = df['date'].dt.year.unique()
dfs = []
for i in range(outputyears):
    dfs.append(winters.query("Year == %d"  %np.random.choice(years, 1)))
    dfs.append(springs.query("Year == %d"  %np.random.choice(years, 1)))
    dfs.append(summers.query("Year == %d"  %np.random.choice(years, 1)))
    dfs.append(autumns.query("Year == %d"  %np.random.choice(years, 1)))

rnd = pd.concat(dfs)

第一个<ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content" android:fillViewport="true" > <TextView android:id="@+id/textview_about" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textIsSelectable="true" android:textSize="20dp" /> </ScrollView> 命令使用2个正则表达式在longstring="(Dfa_and_Cfa && Second_Up_or_Down && Third_Down_or_Up_or_Positive) || (First_Up_or_Down) && Third_Down_or_Up && Dfa_and_Cfa && Third_Down_or_Up && Fourth_Up_or_Down" printf "%s" "${longstring}" | sed -e 's/\(&&\)/\1\n/g' -e 's/\(||\)/\1\n/g' |\ awk -v maxlen=70 '{ stringlen=length(string); if (stringlen == 0 || ((stringlen + length($0)) <= maxlen)) string=string $0 else { print string; string=$0}} END {if (length(string)>0) print string}' (Dfa_and_Cfa && Second_Up_or_Down && Third_Down_or_Up_or_Positive) || (First_Up_or_Down) && Third_Down_or_Up && Dfa_and_Cfa && Third_Down_or_Up && Fourth_Up_or_Down sed之后添加新行。

&&命令读取每一行(||)并构建一个awk,这是行的串联。如果$0string的长度总和超过string(70),则会打印当前$0,并将maxlen设置为当前行。

答案 3 :(得分:0)

使用awk的一个解决方案:

代码:

echo $long_string | awk -F'[&][&]|[|][|]' '{ for(i=1;i<NF;i++) print $i }' | awk  '{if(length($0)<70) print}' 

解释:

我用空格分隔字段:

 for(i=1;i<NF;i++) print $i

然后我用管道消耗输出,只有当长度小于70时才打印:

 | awk  '{if(length($0)<70) print}'

我想使用短于70的剩余字段,你必须添加一个管道(|)并添加另一个命令