使用sed进行标记和捕获

时间:2015-05-22 19:22:18

标签: regex bash awk sed

假设我们有一个字符串 "dir1|file1|dir2|file2"

并希望将其变成 "-f dir1/file1 -f dir2/file2"

对于n>的一般情况,使用sed或awk是否有一种优雅的方法? 2?

我的尝试是尝试

echo "dir1|file1|dir2|file2" | sed 's/\(\([^|]\)|\)*/-f \2\/\4 -f \6\/\8/'

4 个答案:

答案 0 :(得分:2)

awk解决方案:

awk -F'|' '{ for (i=1;i<=NF;i+=2) printf "-f %s/%s%s", $i, $(i+1), ((i==NF-1) ? "\n" : " ") }'  \
  <<<"dir1|file1|dir2|file2"
  • -F'|'将输入按|
  • 拆分为字段
  • for (i=1;i<=NF;i+=2)循环遍历字段索引,增量为2
  • printf "-f %s/%s%s", $i, $(i+1), ((i==NF-1) ? "\n" : " ")打印与/相关联的连续字段对,并以-f<space>为前缀
    • ((i==NF-1) ? "\n" : " ")使用空格终止每个字段对,如果有更多字段,或\n终止整体输出。

在评论中,OP建议更短的变化,如果您不需要/希望输出为\n,则可能会感兴趣 - 终止:

awk -F'|' '{ for (i=1;i<=NF;++i) printf "%s", (i%2 ? " -f " $i : "/" $i ) }' \
  <<<"dir1|file1|dir2|file2"

答案 1 :(得分:2)

这可能适合你(GNU sed):

sed 's/\([^|]*\)|\([^|]*\)|\?/-f \1\/\2 /g;s/ $//' file

这适用于dir1|file1|dir2|file2|dirn|filen类型字符串

正则表达式形成两个后向引用(\1,\2 used in the replacement part of the substitution command s/pattern/replacement/),第一个是非|,然后是|,第二个是非|'然后是可选的|,即第一次应用替换(NB g标志已实现,因此替换可能是多次)dir1变为\1和{{ 1}}变为file1。剩下的就是前置\2并将第一个-f替换为|,将第二个/替换为空格。该行末尾不需要空格,并在第二个替换命令中删除。

答案 2 :(得分:1)

$ awk -v RS='|' 'NR%2{p=$0;next} {printf " -f %s/%s", p, $0}' <<< 'dir1|file1|dir2|file2'
 -f dir1/file1 -f dir2/file2

答案 3 :(得分:0)

gnu-awk解决方案:

s="dir1|file1|dir2|file2"
awk 'BEGIN{ FPAT="[^|]+\\|[^|]+" } {
    for (i=1; i<=NF; i++) {
       sub(/\|/, "/", $i);
       if (i>1)
          printf " ";
       printf "-f " $i
    };
    print ""
}' <<< "$s"
-f dir1/file1 -f dir2/file2

FPAT用于将dir1|file2抓取到单个字段中。