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



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

输入:

a20201005xy20201209mnkm
b20201001dt20210526nhyg
c        mn20210217bgyt
d        yr20210314vfgy

期望输出:

a20201005xy20201209mnkm
b20201001dt20210526nhyg
c20210217mn20210217bgyt
d20210314yr20210314vfgy

法典:

#!/usr/bin

while read -r line; do
date1=`echo ${line:1:8}`
date2=`echo ${line:11:8}`
echo $date1 $date2
if [[ ${date1} == " " ]]
then
sed -i 's/${date1}/${date2}/g' $line
fi
done < replace

感谢您的帮助!

赛勒斯对awk有一个很好的答案。如果你不能使用FIELDWIDTHS=,你可以对substr()sub()做同样的事情,这将适用于所有awk。您只需使用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只是print记录的简写)

如果你想缩短它一点,你可以简单地删除date变量并用substr()直接替换,例如sub(/[ ]+/,substr($0,12,8),$0),但这可能不太易读。

示例使用/输出

通过您在input.txt中的输入,您将收到:

$ awk '{
>     if (substr($1,2,8) ~ /^[[:blank:]]*$/) {
>         date = substr($0,12,8)
>         sub(/[ ]+/,date,$0)
>     }
> }1' input.txt
a20201005xy20201209mnkm
b20201001dt20210526nhyg
c20210217mn20210217bgyt
d20210314yr20210314vfgy

仔细检查一下,让我知道这是否可行。

使用您显示的示例,请尝试以下操作。

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
  • -pe选项通过放置即时代码来组成类似 awk 的单行代码 作为论据。
  • 变量$_perl的默认变量,它用作模式sed的空间 .
  • substr($_, 1, 8)函数提取从偏移量开始的子字符串 1 和长度 8 的字符串$_,用于保存当前行。
  • 正则表达式/^s+$/测试变量$date1是否仅包含空格。
  • substr()功能可以方便地用作lvalue含义 它可以被分配。声明substr($_, 1, 8) = substr($_, 11, 8);将右侧子字符串复制到左侧子字符串上。

如果你有更多的字段要替换,修改上面的代码会很容易 以满足您的要求。

如果您想使用"sed",请尝试以下操作:

$ sed 's/^(.)        (..)(........)/1323/' input.txt
a20201005xy20201209mnkm
b20201001dt20210526nhyg
c20210217mn20210217bgyt
d20210314yr20210314vfgy

使用gnu-awk您可以尝试以下单行:

awk 'length($1)<8 {$0 = gensub(/[[:blank:]]+/, substr($2, 3, 8), "1")} 1' file
a20201005xy20201209mnkm
b20201001dt20210526nhyg
c20210217mn20210217bgyt
d20210314yr20210314vfgy

相关内容

  • 没有找到相关文章

最新更新