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

r6hnlfcb  于 2023-10-18  发布在  Unix
关注(0)|答案(5)|浏览(150)

我有一个名为test的文件,它有:
我想得到有3个单词的行,然后打印它们,而第一个单词是重复的。
我不能使用管道,我可以使用>|把它放到一个临时文件中并从中读取。
所以在这种情况下的输出是:
我或多或少明白我需要什么定期expr,但其余的我挣扎,有人可以请帮助:?
我是这么做的

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

我知道这不是解决方案,但请帮助我理解:

mpbci0fu

mpbci0fu1#

你可以试试这个

$ 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.

^Assert我们正处于起点。(..)称为捕获组,用于捕获字符。稍后,您可以通过反向引用其索引号来引用这些捕获的字符。([^ ]+)捕获任何字符,但不是一个空间一次或多次。+重复上一个令牌一次或多次。$Assert我们在行尾。

$ 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:]]\+匹配一个或多个空格字符。&将打印所有匹配的字符。

py49o6xq

py49o6xq2#

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

awk

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

Plain 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
u5rb5r59

u5rb5r593#

下面是一个只接受单词字符的sed解决方案:

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

sulc1iza4#

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

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

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

zpf6vheq

zpf6vheq5#

重复第一个单词:

sed 's/[^ ]\+ /&&/' input-file

需要三个字:

sed 's/\b//5; T; s/[^ ]\+ /&&/' input-file
  • 尝试替换第五个单词边界(将是第三个单词的开始)
  • 如果失败,则T分支到下一行输入,不执行任何操作
  • 否则s/[^ ]\+/&&/复制第一个字。
    最后,删除少于三个字的行:
sed 's/\b//5; Td; s/[^ ]\+ /&&/; t; :d d' input-file
  • Td到分支以标记:dd,如果有5个字边界则删除
  • t不删除单词较多的行后

都是GNU sed. \+s///5语法都可能需要。

相关问题