如何打印第 n 个分隔符之后的字符串的其余部分(不仅仅是没有分隔符的列)?
我有一个包含一堆注册表项的文本文件,类似于:
hku\test\user\software\microsoft\windows\currentversion\runonce\delete cached update binary
我想打印第三个\
字符之后的所有内容。所以我正在寻找输出
software\microsoft\windows\currentversion\runonce\delete cached update binary
我知道如何使用 打印出特定列awk
,但是有没有简单的方法使用bash
指定分隔符来分割字符串,而不是使用分隔符来打印列?
答案1
管道通过 cut -d \\ -f 4-
。
echo 'hku\test\user\software\microsoft\windows\currentversion\runonce\delete cached update binary' | cut -d \\ -f 4-
产量:
software\microsoft\windows\currentversion\runonce\delete cached update binary
请注意 double \\
,因为 single\
是转义字符。
答案2
和sed
:
sed -E 's/^([^\]*[\]){3}//' infile
或相同awk
:
awk '{ sub(/([^\\]*[\\]){3}/, "") }1' infile
比赛重复(regex)
3次;[^\]*[\]
匹配零个或多个任意字符,但不匹配反斜杠(例外情况下不包括换行符)后跟反斜杠字符。
和 shell (POSIX sh/bash/Korn/zsh) 解决方案:
$ str='hku\test\user\software\microsoft\windows\currentversion\runonce\delete cached update binary'
$ for i in $(seq 3); do str="${str#*\\}"; done
$ printf '%s\n' "$str"
语法${parameter#word}
是参数扩展,从其参数中去除最短的前缀。
答案3
使用awk
:
awk 'BEGIN{FS=OFS="\\"; }{for(i=4;i<NF;i++) printf "%s", $i OFS; print $NF }' input
因为我们要打印第三个\
字符之后的所有内容,所以字段分隔符FS
和输出字段分隔符OFS
设置为\
。FS="\\"
因为 single\
是转义字符。因为\
现在是归档分隔符,所以我们使用 for 循环来打印从归档号 4 到记录的最后一个字段。
或者像这样:
awk 'BEGIN{FS=OFS="\\"; }{for(i=4;i<=NF;i++) printf "%s", $i (i==NF?ORS:OFS) }' input
这里一切都是一样的,但使用了三元运算符。这里的 for 循环将在除最后一个字段之外的所有字段OFS
之后打印。$i
在最后一个字段之后,这将打印ORS
即换行符。
另一种方法:
awk 'BEGIN{OFS="\\"} { n=split($0,arr,OFS); $0=""; for (i=4; i<=n; ++i) $(i-3)=arr[i]; print }' input
这里的 split()
内置函数分割$0
并OFS
创建一个数组arr
。然后 for 循环将记录的每个字段更改为$(i-3)=arr[i]
。例如,对于 for 循环的第一个元素,$1
将为 arr[4]。为什么$1
因为$(4-3)
是$1
。当循环完成时,awk
新$0
记录从旧记录的第四个字段 ( $0
) 开始。然后 print 命令打印 new $0
。
答案4
只是为了不要错过perl
:
perl -e '@a=split /\\/, $ARGV[0]; print(join("\\", splice @a, 3), "\n")' $str
str
路在哪里。
或者没有结尾的新行:
perl -e '@a=split /\\/, $ARGV[0]; print join "\\", splice @a, 3' $str