Bash awk-仅按第一次出现进行拆分
我有这样一句话:Bash awk-仅按第一次出现进行拆分,bash,awk,Bash,Awk,我有这样一句话: one:two:three:four:five:six seven:eight 我想用awk把$1变成一,把$2变成2:3:4:5:6:7:8 我知道我可以通过之前的sed获得它。即使用sed更改第一次出现的:,然后使用新的分隔符更改awk 但是,用新的分隔符替换分隔符对我没有帮助,因为我不能保证新的分隔符不会出现在文本中的某个地方 我想知道是否有一个选项可以让awk这样做 比如: awk -F: '{print $1,$2}' 将打印: one two:three:fou
one:two:three:four:five:six seven:eight
我想用awk
把$1
变成一,把$2
变成2:3:4:5:6:7:8
我知道我可以通过之前的sed
获得它。即使用sed
更改第一次出现的:
,然后使用新的分隔符更改awk
但是,用新的分隔符替换分隔符对我没有帮助,因为我不能保证新的分隔符不会出现在文本中的某个地方
我想知道是否有一个选项可以让awk
这样做
比如:
awk -F: '{print $1,$2}'
将打印:
one two:three:four:five:six seven:eight
我还想对$1
和$2
进行一些操作,所以我不想只替换第一次出现的:
这样的东西
echo "one:two:three:four:five:six" | awk '{sub(/:/," ")}1'
one two:three:four:five:six
这会将第一个:
替换为空格。
然后你可以把它换成1美元,2美元
echo "one:two:three:four:five:six" | awk '{sub(/:/," ")}1' | awk '{print $1,$2}'
one two:three:four:five:six
或者在同一个awk中,即使使用替换,您也可以按您喜欢的方式获得1美元和2美元
echo "one:two:three:four:five:six" | awk '{sub(/:/," ");$1=$1;print $1,$2}'
one two:three:four:five:six
编辑:
使用不同的分隔符,您可以首先获得归档的$1
中的一个
,剩下的$2
如下所示:
echo "one:two:three:four:five:six seven:eight" | awk -F\| '{sub(/:/,"|");$1=$1;print "$1="$1 "\n$2="$2}'
$1=one
$2=two:three:four:five:six seven:eight
唯一分隔符
echo "one:two:three:four:five:six seven:eight" | awk -F"#;#." '{sub(/:/,"#;#.");$1=$1;print "$1="$1 "\n$2="$2}'
$1=one
$2=two:three:four:five:six seven:eight
您可以使用GNU awk的
FPAT
:
$ awk '{print $1}' FPAT='(^[^:]+)|(:.*)' file
one
$ awk '{print $2}' FPAT='(^[^:]+)|(:.*)' file
:two:three:four:five:six seven:eight
但是$2
将包含前导分隔符,但您可以使用substr
来修复该问题:
$ awk '{print substr($2,2)}' FPAT='(^[^:]+)|(:.*)' file
two:three:four:five:six seven:eight
因此,把所有这些放在一起:
$ awk '{print $1, substr($2,2)}' FPAT='(^[^:]+)|(:.*)' file
one two:three:four:five:six seven:eight
将子字符串的结果存储回$2
将允许对$2
进行进一步处理,而无需使用前导分隔符:
$ awk '{$2=substr($2,2); print $1,$2}' FPAT='(^[^:]+)|(:.*)' file
one two:three:four:five:six seven:eight
应与mawk 1.3.3配合使用的解决方案:
awk '{n=index($0,":");s=$0;$1=substr(s,1,n-1);$2=substr(s,n+1);print $1}' FS='\0'
one
awk '{n=index($0,":");s=$0;$1=substr(s,1,n-1);$2=substr(s,n+1);print $2}' FS='\0'
two:three:four five:six:seven
awk '{n=index($0,":");s=$0;$1=substr(s,1,n-1);$2=substr(s,n+1);print $1,$2}' FS='\0'
one two:three:four five:six:seven
没有任何替代品
echo "one:two:three:four:five" | awk -F: '{ st = index($0,":");print $1 " " substr($0,st+1)}'
index命令在整个字符串中查找“:”的首次出现,因此在本例中,变量st将设置为4。然后我使用substr函数从位置st+1开始抓取字符串的所有其余部分,如果没有提供结束号,它将转到字符串的结尾。输出为
one two:three:four:five
如果要进行进一步处理,可以始终将字符串设置为变量以进行进一步处理
rem = substr($0,st+1)
注意,这是在Solaris AWK上测试的,但我看不出有任何理由不能在其他口味上使用。OPs的问题不是替代品。它使用delimiterInDect检索字段,我不想对$1和$2进行一些操作。我将编辑我的问题以使其清晰。更新我的答案以使其与请求匹配。更新问题。我无法替换分隔符。因为我不能保证新的分隔符不在text@Jotne阅读问题,OP知道如何使用这种方法,他们表示不想使用这种方法<代码>##
仍然是可能出现在文件中的可打印字符串。echo“一:二:三:四五:六:七”| awk'{$2=substr($2,2);print$1,$2}'FPAT='(^[^::]+)|(:*)结果:一:二:三:四:五:六:七:六:seven@Udy您没有使用GNU awk,或者您使用的是旧版本。。你在运行哪个版本的awk?mawk 1.3.3 1996年11月:)噢,哇!我清楚地声明,对于此解决方案,您需要GNU awk
。你使用的是什么系统?您可能已经有了GNU awk
如果没有,您应该安装最新的gawk
@Udy我已经添加了一个解决方案,它甚至可以与旧的mawk
一起使用。很好的解决方案+1,我可能会显式地设置$2
和NF=2
,这样$3
将不再包含三个ectawk-F:'{n=index]($0,“:”);$2=substr($0,n+1);NF=2;print$1,$2}’
此解决方案给出$1=1$2=2$3=3等。echo“一:二:三:四:五:六:七:八”| awk-F:“{st=index($0,:”);print$1”“substr($0,st+1)}{print$2}'一二:三:四:五:六七:八二
@Jotne你读过答案了吗?Adrain建议将substr
存储在rem
中并使用它。另请看我的评论,它解决了你的两个问题。我可能需要一些睡眠:)@Jotne-没问题,这很容易做到。sudo_O-感谢您的更新和改进。不幸的是,我的天性不是在盘子里给出答案,如果我花时间回答一个问题,那么我希望他们花一点时间理解解决方案。