我有一个名为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
我知道这不是解决办法,但请帮助我理解:/
答案 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,\}
匹配的空格