Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Shell 在Unix中,如果为空,则用固定宽度格式文件中的另一个日期替换日期字段_Shell_Awk_Sed - Fatal编程技术网

Shell 在Unix中,如果为空,则用固定宽度格式文件中的另一个日期替换日期字段

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

我有一个固定宽度的文件。它在每行的位移日期1(1-8)和日期2(11-18)处有两个日期字段。如果date1为空或为空,我想用date2替换date1

输入:

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
  • -pe
    选项通过放置即时代码组成类似于awk的一行程序 作为论据
  • 变量
    $\uu
    perl
    的默认变量,用作模式 sed的空间
    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
  • -pe
    选项通过放置即时代码组成类似于awk的一行程序 作为论据
  • 变量
    $\uu
    perl
    的默认变量,用作模式 sed的空间
    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
/[]+