0

这个问题源于使用 awk 进行字符串模式匹配,基本上我们根据正则表达式模式将一行文本分成多个组,然后只打印两组。现在的问题是我们可以在打印时正确对齐组sed吗?下面是一个例子

$cat input.txt
it is line one
it is longggggggg one
itttttttttt is another one

现在

$sed -e 's/\(.*\) \(.*\) \(.*\) \(.*\)/\1 \3/g' input.txt

它拆分并打印第 1 组和第 3 组,但输出为

it line
it longggggggg
itttttttttt another

我的问题是我们可以做到这一点,sed以便输出为

it                             line
it                      longggggggg
itttttttttt                 another

我做到了,awk但我觉得可以通过sed,但我无法获得如何获得第二组的长度,然后在组之间填充正确数量的空格,我愿意接受任何建议尝试。

4

6 回答 6

2

这可能对您有用(GNU sed):

sed -r 's/^(.*) .* (.*) .*$/\1 \2/;:a;s/^.{1,40}$/ &/;ta;s/^( *)(\S*)/\2\1/' file

或者:

sed -r 's/^(.*) .* (.*) .*$/printf "%-20s%20s" \1 \2/e' file
于 2013-11-03T11:51:37.023 回答
1

您可以在 sed 中使用循环来实现您想要的:

#!/bin/bash
echo 'aa bb cc dd
11 22 33333333 44
ONE TWO THREEEEEEEEE FOUR' | \
sed -e 's/\(.*\) \(.*\) \(.*\) \(.*\)/\1 \3/g' \
-e '/\([^ ]*\) \([^ ]*\)/ { :x ; s/^\(.\{1,19\}\) \(.\{1,19\}\)$/\1  \2/g ; tx }'

两个 19 控制列的宽度。The是一个标签,只要前面的替换成功,就会:x循环到该标签。tx(您可以p;在 tx 之前添加一个“调试”它。

于 2013-11-03T09:19:31.740 回答
0

awk在这种情况下最容易使用...

您也可以使用 bash 循环来计算空间数量并在所覆盖的行上运行此命令:

while read; do
    # ... calculate $SPACE ...
    echo $REPLY|sed "s/\([^\ ]*\)\ *[^\ ]*\ *\([^\ ]*\)/\1$SPACES\2/g"
done < file

但我更喜欢使用awkfor do all that(或其他高级 shell 语言,如 Perl、Python、PHP shell 模式……)

于 2013-11-03T08:51:57.263 回答
0
TemplateSpace="                                                      "
TemplateSize=${#TemplateSpace}

sed "
# split your group (based on word here but depend on your real need)
s/^ *\(\w\) \(\w\) \(\w\) \(\w\).*$/\1 \3/

# align
s/$/${TemplateSpace}/
s/^\(.\{${TemplateSize}\}\).*$/\1/
s/\(\w\) \(\w\)\( *\)/\1 \3\2/
"

或更简单地避免 TemplateSize (并且内容中没有点)

TemplateSpace="............................................................."

并更换

s/^\(.\{${TemplateSize}\}.*$/\1/ 

经过

s/^\(${TemplateSpace}\).*$/\1/
s/\./ /g
于 2013-11-03T09:56:57.970 回答
0

Del 列 2 和 4。右对齐得到的 col 2,行长为 23 个字符。

sed -e '
 s/[^ ]\+/                       /4;
 s/[^ ]\+//2;
 s/^\(.\{23\}\).*$/\1/;
 s/\(^[^ ]\+[ ]\+\)\([^ ]\+\)\([ ]\+\)/\1\3\2/;
'

或带有扩展正则表达式的 gnu sed:

sed -r '
 s/\W+\w+\W+(\w+)\W+\w+$/\1                       /;
 s/^(.{23}).*/\1/;
 s/(+\W)(\w+)(\W+)$/\1\3\2/
'
于 2019-05-22T21:03:31.177 回答
-1

这个问题很老,但我喜欢把它看作一个谜。虽然我喜欢循环解决方案的简洁性,但这里是一个没有循环或 shell 帮助的解决方案。

sed -E "s/ \w+ (\w+) \w+$/ \1/;h;s/./ /g;s/$/#                       /;s/( *)#\1//;x;H;x;s/\n//;s/^( *)(\w+)/\2\1/"

或没有扩展的正则表达式

sed "s/ .* \(.*\) .*$/ \1/;h;s/./ /g;s/$/#                       /;s/\( *\)#\1//;x;H;x;s/\n//;s/^\( *\)\([^ ]*\)/\2\1/"
于 2017-03-18T23:40:05.420 回答