如何使用sed(或bash / perl / awk)提取子字符串并将其写入新列?

时间:2015-06-29 22:37:30

标签: regex bash perl awk sed

我在csv文件(URL)中有一个类似于以下内容的字符串:

https://www.website.com?utm_campaign=blahblahblah&blahblah?SUBSTRING?moreblahblahblahs

我想拉出第二个和第三个问号之间的子字符串并将其写入新列。

任何帮助表示赞赏!谢谢!

5 个答案:

答案 0 :(得分:2)

您可以使用URI模块提取查询字符串。然后提取目标子字符串将更容易。也许更重要的是,更稳定。

示例:

use strict;
use warnings;
use URI;

my $q = 'https://www.website.com/?utm_source=google&utm_medium=cpc&utm_campaign={ifsearch:??s}{?443OZgNf?}_pcrid_{creative}_pkw_{keyword}_pmt_{matchtype}_&utm_term={keyword}??&network={network}&position={adposition}&devicetype={device}';
my $uri = URI->new($q);
my %query = $uri->query_form;
my ($str) = $query{utm_campaign} =~ /{\?([^?]+)\?}/;
print $str;

<强>输出:

443OZgNf

答案 1 :(得分:0)

您可以使用此正则表达式(Perl风格):

s/^.*?\?.*?\?(.*?)\?.*$/$1/

例如:

$ echo 'https://www.website.com?utm_campaign=blahblahblah&blahblah?SUBSTRING?moreblahblahblahs' | perl -lpe 's/^.*?\?.*?\?(.*?)\?.*$/$1/'
SUBSTRING

答案 2 :(得分:0)

你还没有解释什么&#34;写一个新专栏&#34;意味着你可以拔出&#34; 443OZgNf&#34;

首先,作为简写,让我们为您的两个长网址定义变量:

$ url='https://www.website.com/?utm_source=google&utm_medium=cpc&utm_campaign={ifsearch:‌​s}{?443OZgNf?}_pcrid_{creative}_pkw_{keyword}_pmt_{matchtype}_&utm_term={keyword}‌​&network={network}&position={adposition}&devicetype={device}'
$ url2='https://www.website.com?utm_campaign=blahblahblah&blahblah?SUBSTRING?moreblahblahblahs'

使用awk

使用awk,我们可以将?定义为字段分隔符,然后打印第三个字段:

$ echo "$url" | awk -F'?' '{print $3}'
443OZgNf
$ echo "$url2" | awk -F'?' '{print $3}'
SUBSTRING

-F'?'将字段分隔符更改为问号。 print $3打印第三个字段

使用sed

$ echo "$url" | sed -r 's/([^?]*[?]){2}([^?]*)[?].*/\2/'
443OZgNf
$ echo "$url2" | sed -r 's/([^?]*[?]){2}([^?]*)[?].*/\2/'
SUBSTRING

此处,([^?]*[?]){2}匹配前两个问号的所有文本。 ([^?]*)匹配第二个和第三个?之间的所有文字,并保存第2组中的文字。[?].*匹配第三个问号及其后的所有文字。

使用tr和sed

$ echo "$url" | tr '?' '\n' | sed -n '3p'
443OZgNf
$ echo "$url2" | tr '?' '\n' | sed -n '3p'
SUBSTRING

答案 3 :(得分:0)

在原生bash中,假设网址位于文件的第三列,并且我们不需要在其数据中处理包含文字,的列:

while IFS=, read first second url rest; do
    url_piece=${url#*"?"*"?"}    # trim everything up to the second "?"
    url_piece=${url_piece%%"?"*} # trim everything after the first "?" in what's left

    # print variables with commas after them...
    printf -v out '%s,' "$first" "$second" "$url" "$rest" "$url_piece"
    # ...and print to stdout without the last comma.
    printf '%s\n' "${out%,}"
done <in.csv >out.csv

答案 4 :(得分:0)

如果我理解你想要从第2个和第3个?之间拉出文本并将其附加到字符串的末尾,那么会有一个简短的脚本:

#!/bin/bash

infile=${1:-/dev/stdin}

while read -r line; do
    printf "%s %s\n" "$line" $(sed -e 's/^.*[?].*[?]\(.*\)[?].*$/\1/' <<<"$line")
done <"$infile"

<强>输出

$ bash parseurl.sh url.txt
https://www.website.com?utm_campaign=blahblahblah&blahblah?SUBSTRING?moreblahblahblahs SUBSTRING

如果我没有正确理解,请告诉我,我会重做它。