awk / sed在每一行中替换为该行中的前一个字符串

时间:2016-09-01 14:03:21

标签: bash awk sed

我有一个这样的文件test.txt(但包含更多行)

/foo/bar/how hello
/foo/bar/are hello
/foo/bar/you hello

我想得到这个输出:

/foo/bar/how how
/foo/bar/are are
/foo/bar/you you

我试过这个:

while read line
do
bla=$(echo $line | cut -f4 -d"/" | cut -f1 -d" ")
sed -i "s/hello/$bla/"
done <test.txt

但输出是:

sed: no input files
sed: no input files
sed: no input files

当我提供文件名(while read line; do bla=$(echo $line | cut -f4 -d"/" | cut -f1 -d" "); sed -i "s/hello/$bla/" test.txt ; done <test.txt)时,我明白了:

/foo/bar/how how
/foo/bar/are how
/foo/bar/you how

我想在每一行上用一个出现在同一行之前的模式替换一些常量模式,并且逐行变化。关于我如何做到这一点的任何想法(使用sed或awk)?非常感谢!

3 个答案:

答案 0 :(得分:2)

$ sed 's~\([^/]*\) .*~\1 \1~' file
/foo/bar/how how
/foo/bar/are are
/foo/bar/you you

答案 1 :(得分:2)

低于awk解决方案可能会有所帮助

awk  '{$2=$1;sub(/.*\//,"",$2)}1' test.txt

<强>输出继电器

/foo/bar/how how
/foo/bar/are are
/foo/bar/you you

备注

  • 默认情况下,awk字段是以空格分隔的,因此您有两个字段,即$1$2
  • 首先将每条记录的第一个字段分配给第二个,即$2=$1
  • 然后,在第二个字段中,使用/将部分剥离到最后sub(/.*\//,"",$2)
  • 1最后是最简单的awk命令,用于打印每条记录。

答案 2 :(得分:1)

试试这个:

$ sed 's~\(.*/\)\([^ ]*\) .*~\1\2 \2~' test.txt
/foo/bar/how how
/foo/bar/are are
/foo/bar/you you

使用-i选项编辑文件

sed -i 's~\(.*/\)\([^ ]*\) .*~\1\2 \2~' test.txt

<强>解释

  • s:替换
  • \(.*/\)\:任何字符,最后为/
  • 后跟\([^ ]*\):任何非空格字符后跟空格

使用反向引用,匹配模式的字符串将替换为:第一个组(/foo/bar/),然后是重复的第二个组(最后一个/之后的单词:how,{{1 }或are)。