问题描述
背景
我有一个文本文件,如下所示:
$SomeText.element_[1]="MoreText[3]";\r"
$SomeText.element_[2]="MoreText[6]";\r"
$SomeText.element_[3]="MoreText[2]";\r"
$SomeText.element_[4]="MoreText[1]";\r"
$SomeText.element_[5]="MoreText[5]";\r"
这持续了超过一千行。我要执行以下操作:
$SomeText.element_[0]="MoreText[3]";\r"
$SomeText.element_[1]="MoreText[6]";\r"
$SomeText.element_[2]="MoreText[2]";\r"
$SomeText.element_[3]="MoreText[1]";\r"
$SomeText.element_[4]="MoreText[5]";\r"
文件中的每一行文本的最左边索引应减少一,其余文本保持不变。
尝试的解决方案
到目前为止,我已经尝试了以下方法...但是对我来说,问题是我不知道如何将其正确地反馈回文件中:
尝试1
我尝试了双重切割技术:
cat file.txt | cut -d '[' -f2 | cut -d ']' -f1 | xargs -I {} expr {} + 1
这会将所有减少了1的索引正确地输出到命令行。
尝试2
我尝试将awk与sed混合使用,但这是由机器挂起引起的:
awk -F'[' '{printf("%d\n",$2-1)}' file.txt | xargs -I {} sed -i 's/\[\d+\]/{}/g' file.txt
问题
如何正确地将文件中的所有数组索引减1,然后将已减少的索引正确写入文本文件的正确位置?
解决方法
Perl单行代码可以很容易地覆盖输入文件:
perl -pi -e 's/(\d+)/$1-1/e' your-file-name-here
(假设每行的第一个数字是索引)
,使用简单的awk
,您可以尝试按照所示示例进行跟踪,编写和测试。
awk '
match($0,/\[[^]]*/){
print substr($0,1,RSTART) count++ substr($0,RSTART+RLENGTH)
}
' Input_file
或者如果您的Input_file的计数在[..]
之间以任意顺序计数,则只需按照以下方法从它们中减少1
。
awk '
match($0,RSTART) substr($0,RSTART+1,RLENGTH)-1 substr($0,RSTART+RLENGTH)
}
' Input_file
,
使用GNU sed
和bash
:
sed -E "s/([^[]*\[)([0-9]+)(].*)/printf '%s%d%s\n' '\1' \$((\2 - 1)) '\3'/e" file
或者,如果行中可能包含'
字符:
sed -E "
/\[[0-9]+]/{
s/'/'\\\''/g
s/([^[]*\[)([0-9]+)(].*)/printf '%s%d%s\n' '\1' \$((\2 - 1)) '\3'/e
}" file