通过脚本

时间:2016-08-02 17:46:33

标签: bash shell

我正在尝试在&DEST=和下一个&或换行符之间获取子字符串。 例如:

  1. MYREQUESTISTO8764GETTHIS&DEST=SFO&ORIG=6546

    在此我需要提取“SFO”

  2. MYREQUESTISTO8764GETTHIS&DEST=SANFRANSISCO&ORIG=6546

    在此,我需要提取“SANFRANSISCO”

  3. MYREQUESTISTO8764GETTHISWITH&DEST=SANJOSE

    在此我需要提取“SANJOSE”

  4. 我正在逐行读取文件,我需要在&DEST=之后更新文本并将其放回文件中。修改文本是用X字符掩盖dest值。

    因此,SFO应替换为XXX。 应将SANJOSE替换为XXXXXXX。

    输出: MYREQUESTISTO8764GETTHIS&DEST=XXX&ORIG=6546 MYREQUESTISTO8764GETTHIS&DEST=XXXXXXXXXXXX&ORIG=6546 MYREQUESTISTO8764GETTHISWITH&DEST=XXXXXXX

    请让我知道如何在脚本中实现这一点(最好是shell或bash脚本)。

    感谢。

4 个答案:

答案 0 :(得分:2)

$ cat file
MYREQUESTISTO8764GETTHIS&DEST=SFO&ORIG=6546
MYREQUESTISTO8764GETTHIS&DEST=PORTORICA
MYREQUESTISTO8764GETTHIS&DEST=SANFRANSISCO&ORIG=6546
MYREQUESTISTO8764GETTHISWITH&DEST=SANJOSE
$ sed -E 's/^.*&DEST=([^&]*)[&]*.*$/\1/' file
SFO
PORTORICA
SANFRANSISCO
SANJOSE

应该这样做

答案 1 :(得分:1)

用相同数量的X替换机场

让我们考虑一下这个测试文件:

$ cat file
MYREQUESTISTO8764GETTHIS&DEST=SFO&ORIG=6546
MYREQUESTISTO8764GETTHIS&DEST=SANFRANSISCO&ORIG=6546
MYREQUESTISTO8764GETTHISWITH&DEST=SANJOSE

使用等长&DEST=并使用GNU sed替换X之后的字符串:

$ sed -E ':a; s/(&DEST=X*)[^X&]/\1X/; ta' file
MYREQUESTISTO8764GETTHIS&DEST=XXX&ORIG=6546
MYREQUESTISTO8764GETTHIS&DEST=XXXXXXXXXXXX&ORIG=6546
MYREQUESTISTO8764GETTHISWITH&DEST=XXXXXXX

要就地替换文件:

sed -i -E ':a; s/(&DEST=X*)[^X&]/\1X/; ta' file

以上用GNU sed测试。对于BSD(OSX)sed,请尝试:

sed -Ee :a -e 's/(&DEST=X*)[^X&]/\1X/' -e ta file

或者,要使用BSD(OSX)sed进行就地更改,请尝试:

sed -i '' -Ee :a -e 's/(&DEST=X*)[^X&]/\1X/' -e ta file

如果有一些原因,为什么使用shell逐行读取文件很重要:

while IFS= read -r line
do
   echo "$line" | sed -Ee :a -e 's/(&DEST=X*)[^X&]/\1X/' -e ta
done <file

如何运作

让我们考虑一下这段代码:

search_str="&DEST="
newfile=chart.txt
sed -E ':a; s/('"$search_str"'X*)[^X&]/\1X/; ta' "$newfile"
  • -E

    这告诉sed使用扩展正则表达式(ERE)。这样做的好处是需要更少的反斜杠来逃避事情。

  • :a

    这会创建一个标签a

  • s/('"$search_str"'X*)[^X&]/\1X/

    这会查找$search_str,后跟任意数量的X,后跟任何不是X&的字符。由于parens,除了最后一个字符之外的所有内容都保存到组1中。此字符串由组1替换,表示为\1X

  • ta

    在sed中,ttest命令。如果进行了替换(意味着某些字符需要被X替换),那么测试评估为true,在这种情况下,ta告诉sed跳转到标签a

    此测试和跳转导致替换被重复多次。

使用一个sed命令替换多个标签

$ name='DEST|ORIG'; sed -E ':a; s/(&('"$name"')=X*)[^X&]/\1X/; ta' file
MYREQUESTISTO8764GETTHIS&DEST=XXX&ORIG=XXXX
MYREQUESTISTO8764GETTHIS&DEST=XXXXXXXXXXXX&ORIG=XXXX
MYREQUESTISTO8764GETTHISWITH&DEST=XXXXXXX

回答原始问题

使用shell

$ s='MYREQUESTISTO8764GETTHIS&DEST=SFO&ORIG=6546'
$ s=${s#*&DEST=}
$ echo ${s%%&*}
SFO

工作原理:

  • ${s#*&DEST=} 前缀删除。这将删除所有文本,包括第一次出现&DEST=

  • ${s%%&*}是后缀remove_。它会删除第一个&到字符串末尾的所有文本。

使用awk

$ echo 'MYREQUESTISTO8764GETTHIS&DEST=SFO&ORIG=6546' | awk -F'[=\n]' '$1=="DEST"{print $2}' RS='&'
SFO

工作原理:

  • -F'[=\n]'

    这告诉awk将等号或换行视为字段分隔符

  • $1=="DEST"{print $2}

    如果第一个字段是DEST,则打印第二个字段。

  • RS='&'

    这会将记录分隔符设置为&

答案 2 :(得分:1)

使用GNU bash:

while IFS= read -r line; do
  [[ $line =~ (.*&DEST=)(.*)((&.*|$)) ]] && echo "${BASH_REMATCH[1]}fooooo${BASH_REMATCH[3]}"
done < file

输出:

MYREQUESTISTO8764GETTHIS&DEST=fooooo&ORIG=6546
MYREQUESTISTO8764GETTHIS&DEST=fooooo&ORIG=6546
MYREQUESTISTO8764GETTHISWITH&DEST=fooooo

答案 3 :(得分:-1)

用x代替from c in _db.Customers from p in _db.Payments.Where(r => r.CustId == c.ID && r.Success).OrderBy(r => r.PaymentDate).Take(1).DefaultIfEmpty() join u1 in _db.Users on c.UserID equals u1.Id into us from use1 in us.DefaultIfEmpty() && (byCard == "1" ? p!=null : true) &DEST(或EOL)之间的字符:

&