我有一个具有以下结构的文件:
# #################################################################
# 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
它打印出文件,但它包含描述值和标签,如果它们包含空格或短划线,则剪切值。这只是一团糟。
我根据我在Stack Overflow和一些博客上发现的内容尝试了更多命令,但我没需要什么。
注意:描述标记的值不是锯齿状的 - 这是因为我以单独的方式将它们写入文件。
我的命令出了什么问题?我如何实现我的需求?
答案 0 :(得分:1)
你可以使用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将其重新组合在一起。
答案 1 :(得分:1)
当您的文件没有标签时,请尝试以下操作:
sed -r 's/: +/:\t/' file.txt | expand -20
当此方法有效时,将输出重定向到tmp文件并将tmpfile移动到file.txt
。
答案 2 :(得分:0)
您可以使用\ t来插入标签(而不是空格,这就是为什么会出现锯齿状的'值)
而不是
sed -i -r "\$a$PROPERTY1: VALUE1_3" file.txt
使用
sed -i -r "\$a$PROPERTY1:\t\tVALUE1_3" file.txt
答案 3 :(得分:0)
您需要做的就是在插入新行时记住现有的缩进,例如:
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。
如果你的“属性”实际上并不是以“属性”一词开头,那么你只需要编辑你的问题以显示更真实的样本输入/输出,并告诉/告诉我们如何区分属性行和描述行,再次,使用awk解决方案将是微不足道的。