如何使用sed将包含3个单词的行中的第一个单词加倍?

时间:2015-01-14 13:56:16

标签: regex bash unix sed

我有一个名为test的文件,其中包含:

1 2 3
2 3
4 5 6 7
8 9 10
11 12 13 14 15 16 17
18 19 20

我想得到包含3个单词的行,然后打印出来,而第一个单词是重复的。

我无法使用管道,我可以使用> |把它放在一个tmp文件中并从中读取。

所以这种情况下的输出是:

1 1 2 3
8 8 9 10
18 18 19 20

我或多或少地了解我需要的常规expr,但其余的我正在努力,有人可以帮忙:?

这就是我所做的:

sed 's/'^[^ ]*[ ]+[^ ]+[ ]+[^ ]+[ ]*$'/&&/1/ test

我知道这不是解决办法,但请帮助我理解:/

4 个答案:

答案 0 :(得分:3)

你可以试试这个,

$ sed -nr 's/^([^ ]+) +[^ ]+ +[^ ]+$/\1 &/p' file
1 1 2 3
8 8 9 10
18 18 19 20

来自man sed

-n, --quiet, --silent
             suppress automatic printing of pattern space
p      Print the current pattern space.

^断言我们刚开始。 (..)称为捕获组,用于捕获字符。稍后您可以通过反向引用它们的索引号来引用这些捕获的字符。 ([^ ]+)捕获任何字符,但不能捕获空格一次或多次。 +重复前一个令牌一次或多次。 $声称我们处于行尾。

$ sed -n 's/^\([^[:blank:]]\+\)\([[:blank:]]\+\)[^[:blank:]]\+[[:blank:]]\+[^[:blank:]]\+$/\1\2&/p' file
1 1 2 3
8 8 9 10
18 18 19 20

[^[:blank:]]\+匹配一个或多个非空格字符。 [[:blank:]]\+匹配一个或多个空格字符。替换部分中的&将打印所有匹配的字符。

答案 1 :(得分:2)

sed不是空格分隔数据的首选工具。由于已经有答案使用sed这里有一些替代方案:

<强> AWK

awk 'NF==3 { print $1, $1, $2, $3 }' < test

普通POSIX shell

#!/bin/sh
while IFS=' ' read -r a b c d; do
    if [ ! -z "$a" -a ! -z "$b" -a ! -z "$c" -a -z "$d" ]; then
        echo "$a $a $b $c";
    fi
 done < test

答案 2 :(得分:1)

以下是sed解决方案,仅采用单词字符:

$ sed -n "s/^\(\([a-zA-Z0-9]\+\) [a-zA-Z0-9]\+ [a-zA-Z0-9]\+$\)/\2 \1/p" test.txt

答案 3 :(得分:0)

# Posix
sed '/^\([^ ]\{1,\}\)\( [^ ]\{1,\}\)\{2\}$/ !d;s//\1 &/' YourFile

# GNU
sed '/^([^ ]+)( [^ ]+){2}$/ !d;s//\1 &/' YourFile

假设空间只有1个空格字符(如果不是,只需更改与[[:space:]]\{1,\}匹配的空格