【问题标题】:Awk/sed replace in each line with previous string in the lineawk/sed 用该行中的前一个字符串替换每一行
【发布时间】:2017-09-24 00:36:24
【问题描述】:

我有一个像这样的文件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 &lt;test.txt) 时,我得到了这个:

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

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

【问题讨论】:

  • 您需要在sed -i "s/hello/$bla/"右侧向sed提供文件作为输入

标签: bash awk sed


【解决方案1】:
$ sed 's~\([^/]*\) .*~\1 \1~' file
/foo/bar/how how
/foo/bar/are are
/foo/bar/you you

【讨论】:

  • 谢谢!如另一个答案中所述,您能解释一下吗?如果我想让它适应其他字符串:)
  • sed 与字符串不匹配。如果你想匹配字符串,那么你应该使用 awk。我不是在开玩笑——这是一个非常重要的教训。给定的脚本搜索以非/字符序列开头的正则表达式(并捕获与该 RE 段匹配的子字符串),然后是一个空白字符,然后是其他任何字符,然后用捕获的子字符串替换整个匹配字符串一个空白然后再次捕获的子字符串。我使用~ 而不是更常见的/ 来分隔脚本段,以避免在正则表达式中转义/
  • 好的,我真的很想基于模式 --> 我编辑我的帖子!
  • 避免单独使用pattern这个词,因为它非常模棱两可——只要说出你的意思:stringregexpglobbing pattern或别的什么。对您的问题的编辑尚不清楚,但听起来您正在走上一条小路。不要创建chameleon question。您问了一个特定问题,您得到了特定问题的答案,现在只需选择一个答案即可接受,如果您有后续问题,请使用清晰、简洁、可测试的示例输入和预期输出发布新问题。
  • 哦,请确保您的示例输入以及您想要匹配或替换的任何字符串都包含空格和正则表达式元字符以及反向引用元字符和 sed 分隔符 (/) 以及您认为可能是的任何其他内容如果它们可能出现在您的真实数据中,则存在问题。还要确保包含与您的搜索条件不匹配的行。将样本设为最坏情况,而不是最好情况,彩虹和蝴蝶情况,否则您将得到仅适用于该情况的答案!
【解决方案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 命令,用于打印每条记录。

【讨论】:

    【解决方案3】:

    试试这个:

    $ 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/),然后是重复的第二组(最后一个 / 之后的单词:howareyou)。

    【讨论】:

    • 谢谢@Kenavoz!你能解释一下你的命令吗? sed 对我来说有点晦涩;)
    猜你喜欢
    • 1970-01-01
    • 2012-09-13
    • 2015-01-02
    • 1970-01-01
    • 2016-10-29
    • 1970-01-01
    • 1970-01-01
    • 2020-01-12
    • 1970-01-01
    相关资源
    最近更新 更多