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
将不再包含
三个
ect
awk-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-感谢您的更新和改进。不幸的是,我的天性不是在盘子里给出答案,如果我花时间回答一个问题,那么我希望他们花一点时间理解解决方案。