SED/AWK:在一个文件
我有以下结构的文件对齐的话:SED/AWK:在一个文件
# #################################################################
# TEXT: MORE TEXT
# TEXT: MORE TEXT
# #################################################################
___________________________________________________________________
ITEM 1
___________________________________________________________________
PROPERTY1: VALUE1_1
PROPERTY222: VALUE2_1
PROPERTY33: VALUE3_1
PROPERTY4444: VALUE4_1
PROPERTY55: VALUE5_1
Description1: Some text goes here
Description2: Some text goes here
___________________________________________________________________
ITEM 2
___________________________________________________________________
PROPERTY1: VALUE1_2
PROPERTY222: VALUE2_2
PROPERTY33: VALUE3_2
PROPERTY4444: VALUE4_2
PROPERTY55: VALUE5_2
Description1: Some text goes here
Description2: Some text goes here
我想其他项目添加到该文件,使用SED或AWK:
sed -i -r "\$a$PROPERTY1: VALUE1_3" file.txt
sed -i -r "\$a$PROPERTY2222: VALUE2_3" file.txt
等等。因此,我的下一个项目是这样的:
___________________________________________________________________
ITEM 3
___________________________________________________________________
PROPERTY1: VALUE1_3
PROPERTY222: VALUE2_3
PROPERTY33: VALUE3_3
PROPERTY4444: VALUE4_3
PROPERTY55: VALUE5_3
Description1: Some text goes here
Description2: Some text goes here
列值是参差不齐的。如何像以前的项目一样将我的值与左侧对齐?我可以在这里看到2个解决方案:
- 在将值插入文件时对齐值。
- 按照我所做的方式将值插入到文件中,然后将它们对齐。
命令
sed -i -r "s|.*:.*|&|g" file.txt
渔获物的属性和值我要对齐,但我一直没能正确地对准他们,即
awk '/^.*:.*$/{ printf "%-40s %-70s\n", $1, $2 }' file.txt
它打印出的文件,但它包含描述值和标签,如果它们包含空格或破折号,则将其剪切。这只是一个大混乱。
我已经尝试了更多的命令,基于我在堆栈溢出和一些博客上找到的内容,但没有做任何我需要的。
注意:描述标记的值不是参差不齐 - 这是因为我以单独的方式将它们写入文件。
我的命令有什么问题?我如何实现我所需要的?
当你的文件是没有标签,试试这个:
sed -r 's/: +/:\t/' file.txt | expand -20
在这个作品中,输出重定向到一个TMPFILE并移动到TMPFILE file.txt
。
你可以使用\ t插入选项卡(而不是空格这就是为什么你会得到 '锯齿' 值)
,而不是
sed -i -r "\$a$PROPERTY1: VALUE1_3" file.txt
使用
sed -i -r "\$a$PROPERTY1:\t\tVALUE1_3" file.txt
使用标签仍然可能导致锯齿状对齐,当一个按键的长度是例如两个选项卡(加上一些空格)长,另一个键是三个选项卡(再加上一些空格)。 – Heinrich
@ M.B。无论我插入制表符还是空格,属性的名称都不相同,所以我总是会得到锯齿值。 – user2738748
您可以使用gensub和周到的领域分离器照顾到这一点:
for i in {1..5}; do
echo $((10 ** i)): $i;
done | awk -F ':::' '/^[^:]+:.+/{
$0 = gensub(/: +/, ":::", $0);
key=($1 ":");
printf "%-40s %s\n", key, $2;
}'
相关部分是我们将“:+”替换为“:::”的位置,然后执行printf将其重新组合。
你正在错误地调用gensub()(你正在用'$ 0'填充“多少个替换项”字段),你不需要字符串连接的parens,你不需要尾随换行符,我无法想象改变':+'到':::'并将FS设置为':::'应该做的不是将FS设置为':+'(谁说':::'不存在于VALUE?)或者只是使用几个sub()。哦,你应该提到它是由于使用'gensub()'而引起的特定于gawk的。 –
所有你需要做插入新线时,如被记现有的压痕:
echo 'PROPERTY732: VALUE9_8_7' |
awk -v prop="PROPERTY1" -v val="VALUE1_3" '
match($0,/^PROPERTY[^[:space:]]+[[:space:]]+/) { wid=RLENGTH }
{ print }
END { printf "%-*s%s\n", wid, prop":", val }
'
PROPERTY732: VALUE9_8_7
PROPERTY1: VALUE1_3
但是,加入1线同时是有道理,还是现在还不清楚,所有的其他文字的你'重新补充来自于。
上述内容适用于任何UNIX系统上的任何awk。
如果您的“属性”实际上并没有以PROPERTY开头,那么您只需编辑您的问题以显示更加真实的示例输入/输出,并告诉/告诉我们如何区分PROPERTY行和Description行;再一次,这个解决方案对于awk来说是微不足道的。
尽管可以使用sed/awk解决这个问题,但使用更强大的工具可能会更容易解决这个问题。您是否考虑过使用正确的数据结构的完整编程语言(例如perl,ruby,C++)来解决您的问题? – Heinrich
@海因里希,我想避免使用完整的编程语言,因为我在bash中有一个几乎完整的脚本,完全符合我的要求,这是它唯一的问题。由于这个问题(并非如此严重),我不希望强迫脚本的用户安装不同语言的编译器或解释器。 – user2738748