Shell 在Unix中,如果为空,则用固定宽度格式文件中的另一个日期替换日期字段
我有一个固定宽度的文件。它在每行的位移日期1(1-8)和日期2(11-18)处有两个日期字段。如果date1为空或为空,我想用date2替换date1 输入:Shell 在Unix中,如果为空,则用固定宽度格式文件中的另一个日期替换日期字段,shell,awk,sed,Shell,Awk,Sed,我有一个固定宽度的文件。它在每行的位移日期1(1-8)和日期2(11-18)处有两个日期字段。如果date1为空或为空,我想用date2替换date1 输入: a20201005xy20201209mnkm b20201001dt20210526nhyg c mn20210217bgyt d yr20210314vfgy 期望输出: a20201005xy20201209mnkm b20201001dt20210526nhyg c20210217mn20210217
a20201005xy20201209mnkm
b20201001dt20210526nhyg
c mn20210217bgyt
d yr20210314vfgy
期望输出:
a20201005xy20201209mnkm
b20201001dt20210526nhyg
c20210217mn20210217bgyt
d20210314yr20210314vfgy
代码:
#/usr/bin
而read-r行;做
date1=`echo${line:1:8}`
date2=`echo${line:11:8}`
echo$date1$date2
如果[${date1}==“”]]
然后
sed-i的/${date1}/${date2}/g'$行
fi
完成<更换
谢谢你的帮助 赛勒斯对awk的回答很好。如果不能使用
FIELDWIDTHS=
,则可以使用substr()
和sub()
执行相同的操作,这将适用于所有awk
s。只需使用substr()
检查以字符2开头的8字符子字符串中的所有字符是否都是空白字符([[:blank:]
)。如果是,您只需将其替换为从字符12开始的8个字符的子字符串,例如
awk '{
if (substr($1,2,8) ~ /^[[:blank:]]*$/) {
date = substr($0,12,8)
sub(/[ ]+/,date,$0)
}
}1' input.txt
(注意:结尾的1
只是打印
记录的简写)
如果您想将其缩短一点,只需删除date
变量,并直接使用substr()
进行替换,例如sub(/[]+/,substr($0,12,8),$0)
,但可读性可能稍差
示例使用/输出
通过在input.txt
中输入,您将收到:
$awk'{
>if(substr($1,2,8)~/^[:blank:]*$/){
>日期=substr($0,12,8)
>子(/[]+/,日期,$0)
> }
>}1'input.txt
A2020105XY20201209MNKM
B202001001DT20210526NHYG
C20210217MN20217BGYT
D20210314YR2010314VFGY
仔细检查一下,让我知道这是否有效。塞勒斯用
awk
给出了一个很好的答案。如果不能使用FIELDWIDTHS=
,则可以使用substr()
和sub()
执行相同的操作,这将适用于所有awk
s。只需使用substr()
检查以字符2开头的8字符子字符串中的所有字符是否都是空白字符([[:blank:]
)。如果是,您只需将其替换为从字符12开始的8个字符的子字符串,例如
awk '{
if (substr($1,2,8) ~ /^[[:blank:]]*$/) {
date = substr($0,12,8)
sub(/[ ]+/,date,$0)
}
}1' input.txt
(注意:结尾的1
只是打印
记录的简写)
如果您想将其缩短一点,只需删除date
变量,并直接使用substr()
进行替换,例如sub(/[]+/,substr($0,12,8),$0)
,但可读性可能稍差
示例使用/输出
通过在input.txt
中输入,您将收到:
$awk'{
>if(substr($1,2,8)~/^[:blank:]*$/){
>日期=substr($0,12,8)
>子(/[]+/,日期,$0)
> }
>}1'input.txt
A2020105XY20201209MNKM
B202001001DT20210526NHYG
C20210217MN20217BGYT
D20210314YR2010314VFGY
仔细检查一下,让我知道这是否有效。对于您展示的样品,请尝试以下内容
awk '
match($0,/^[a-z][[:space:]]{8}/){
val=substr($0,RSTART,RLENGTH)
val2=substr($0,12,8)
sub(/[[:space:]]+$/,val2,val)
$0=val substr($0,RSTART+RLENGTH)
}
1
' Input_file
说明:添加上述内容的详细说明
awk ' ##Starting awk program from here.
match($0,/^[a-z][[:space:]]{8}/){ ##using match function to match from starting with small letter followed by 8 spaces.
val=substr($0,RSTART,RLENGTH) ##Creating val which has matched sub string.
val2=substr($0,12,8) ##Creating val2 with sub string of 8 characters.
sub(/[[:space:]]+$/,val2,val) ##Substituting spaces in val with val2.
$0=val substr($0,RSTART+RLENGTH) ##Creating current line with value of val and sub string of matched string.
}
1 ##Printing current line.
' Input_file ##Mentioning Input_file name here.
有了您展示的样品,请尝试以下内容
awk '
match($0,/^[a-z][[:space:]]{8}/){
val=substr($0,RSTART,RLENGTH)
val2=substr($0,12,8)
sub(/[[:space:]]+$/,val2,val)
$0=val substr($0,RSTART+RLENGTH)
}
1
' Input_file
说明:添加上述内容的详细说明
awk ' ##Starting awk program from here.
match($0,/^[a-z][[:space:]]{8}/){ ##using match function to match from starting with small letter followed by 8 spaces.
val=substr($0,RSTART,RLENGTH) ##Creating val which has matched sub string.
val2=substr($0,12,8) ##Creating val2 with sub string of 8 characters.
sub(/[[:space:]]+$/,val2,val) ##Substituting spaces in val with val2.
$0=val substr($0,RSTART+RLENGTH) ##Creating current line with value of val and sub string of matched string.
}
1 ##Printing current line.
' Input_file ##Mentioning Input_file name here.
如果您选择
perl
,请尝试以下操作:
perl -pe '
$date1 = substr($_, 1, 8);
if ($date1 =~ /^\s+$/) {
substr($_, 1, 8) = substr($_, 11, 8);
}
' file > newfile
$ sed 's/^\(.\) \(..\)\(........\)/\1\3\2\3/' input.txt
a20201005xy20201209mnkm
b20201001dt20210526nhyg
c20210217mn20210217bgyt
d20210314yr20210314vfgy
选项通过放置即时代码组成类似于awk的一行程序 作为论据-pe
- 变量
是$\uu
的默认变量,用作模式 sed的空间perl
sed
函数提取从偏移量开始的子字符串 保留当前行的字符串substr($,1,8)
$\uu1和长度8
- 正则表达式测试变量
是否只包含空格$date1
函数方便地用作substr()
左值 它可以被分配。语句
substr($\u1,8)=substr($\u11,8)代码> 将右子字符串复制到左子字符串上
满足您的要求。如果您选择的是
perl
,请尝试以下操作:
perl -pe '
$date1 = substr($_, 1, 8);
if ($date1 =~ /^\s+$/) {
substr($_, 1, 8) = substr($_, 11, 8);
}
' file > newfile
$ sed 's/^\(.\) \(..\)\(........\)/\1\3\2\3/' input.txt
a20201005xy20201209mnkm
b20201001dt20210526nhyg
c20210217mn20210217bgyt
d20210314yr20210314vfgy
选项通过放置即时代码组成类似于awk的一行程序 作为论据-pe
- 变量
是$\uu
的默认变量,用作模式 sed的空间perl
sed
函数提取从偏移量开始的子字符串 保留当前行的字符串substr($,1,8)
$\uu1和长度8
- 正则表达式测试变量
是否只包含空格$date1
函数方便地用作substr()
左值 它可以被分配。语句
substr($\u1,8)=substr($\u11,8)代码> 将右子字符串复制到左子字符串上
满足您的要求。如果您想使用“sed”,请尝试以下操作:
perl -pe '
$date1 = substr($_, 1, 8);
if ($date1 =~ /^\s+$/) {
substr($_, 1, 8) = substr($_, 11, 8);
}
' file > newfile
$ sed 's/^\(.\) \(..\)\(........\)/\1\3\2\3/' input.txt
a20201005xy20201209mnkm
b20201001dt20210526nhyg
c20210217mn20210217bgyt
d20210314yr20210314vfgy
如果您想使用“sed”,请尝试以下操作:
perl -pe '
$date1 = substr($_, 1, 8);
if ($date1 =~ /^\s+$/) {
substr($_, 1, 8) = substr($_, 11, 8);
}
' file > newfile
$ sed 's/^\(.\) \(..\)\(........\)/\1\3\2\3/' input.txt
a20201005xy20201209mnkm
b20201001dt20210526nhyg
c20210217mn20210217bgyt
d20210314yr20210314vfgy
使用
gnu awk
您可以尝试以下一种方法:
awk'长度($1)使用gnu-awk
您可以尝试这一行:
awk'length($1)Hi Cyrus-不知何故,您的回复和评论被删除了。尝试了所有三个建议,但均无效。请阅读。Hi Cyrus-不知何故,您的回复和评论被删除了。尝试了所有三个建议,但均无效。请阅读。非常感谢!您的解决方案按预期运行。很高兴它起到了作用。如果您还有其他问题,请告诉我。wrt/[]+