Sed/awk: 对齐文件中的单词
Sed/awk: Aligning words in a file
我有一个具有以下结构的文件:
# #################################################################
# 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", , }' file.txt
它打印出文件,但它包含描述值和标签,如果包含空格或破折号,则会剪切值。真是一团糟。
我已经根据我在 Stack Overflow 和一些博客上找到的内容尝试了更多命令,但没有一个是我需要的。
注意:描述标签的值没有锯齿状 - 这是因为我以单独的方式将它们写入文件。
我的命令有什么问题?我如何实现我所需要的?
您可以使用 \t 插入制表符(而不是空格,这就是您获得 'jagged' 值的原因)
而不是
sed -i -r "$a$PROPERTY1: VALUE1_3" file.txt
使用
sed -i -r "$a$PROPERTY1:\t\tVALUE1_3" file.txt
您可以使用 gensub 和周到的字段分隔符来解决这个问题:
for i in {1..5}; do
echo $(( 10 ** i )): $i;
done | awk -F ':::' '/^[^:]+:.+/{
[=10=] = gensub(/: +/, ":::", [=10=] );
key=( ":" );
printf "%-40s %s\n", key, ;
}'
相关部分是我们将“:+”换成“:::”,然后执行 printf 将其重新组合在一起。
您需要做的就是在插入新行时记住现有的缩进,例如:
echo 'PROPERTY732: VALUE9_8_7' |
awk -v prop="PROPERTY1" -v val="VALUE1_3" '
match([=10=],/^PROPERTY[^[:space:]]+[[:space:]]+/) { wid=RLENGTH }
{ print }
END { printf "%-*s%s\n", wid, prop":", val }
'
PROPERTY732: VALUE9_8_7
PROPERTY1: VALUE1_3
但不清楚一次添加 1 行是否有意义,或者您添加的所有其他文本来自何处。
以上内容适用于任何 UNIX 系统上的任何 awk。
如果您的 "properties" 实际上不是以 属性 这个词开头,那么您只需要编辑您的问题以显示更真实的示例 input/output 和 tell/show 我们如何区分 属性 行和描述行,同样,使用 awk 解决方案也很简单。
当您的文件没有制表符时,试试这个:
sed -r 's/: +/:\t/' file.txt | expand -20
当这有效时,将输出重定向到 tmpfile 并将 tmpfile 移动到 file.txt
。
我有一个具有以下结构的文件:
# #################################################################
# 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", , }' file.txt
它打印出文件,但它包含描述值和标签,如果包含空格或破折号,则会剪切值。真是一团糟。
我已经根据我在 Stack Overflow 和一些博客上找到的内容尝试了更多命令,但没有一个是我需要的。
注意:描述标签的值没有锯齿状 - 这是因为我以单独的方式将它们写入文件。
我的命令有什么问题?我如何实现我所需要的?
您可以使用 \t 插入制表符(而不是空格,这就是您获得 'jagged' 值的原因)
而不是
sed -i -r "$a$PROPERTY1: VALUE1_3" file.txt
使用
sed -i -r "$a$PROPERTY1:\t\tVALUE1_3" file.txt
您可以使用 gensub 和周到的字段分隔符来解决这个问题:
for i in {1..5}; do
echo $(( 10 ** i )): $i;
done | awk -F ':::' '/^[^:]+:.+/{
[=10=] = gensub(/: +/, ":::", [=10=] );
key=( ":" );
printf "%-40s %s\n", key, ;
}'
相关部分是我们将“:+”换成“:::”,然后执行 printf 将其重新组合在一起。
您需要做的就是在插入新行时记住现有的缩进,例如:
echo 'PROPERTY732: VALUE9_8_7' |
awk -v prop="PROPERTY1" -v val="VALUE1_3" '
match([=10=],/^PROPERTY[^[:space:]]+[[:space:]]+/) { wid=RLENGTH }
{ print }
END { printf "%-*s%s\n", wid, prop":", val }
'
PROPERTY732: VALUE9_8_7
PROPERTY1: VALUE1_3
但不清楚一次添加 1 行是否有意义,或者您添加的所有其他文本来自何处。
以上内容适用于任何 UNIX 系统上的任何 awk。
如果您的 "properties" 实际上不是以 属性 这个词开头,那么您只需要编辑您的问题以显示更真实的示例 input/output 和 tell/show 我们如何区分 属性 行和描述行,同样,使用 awk 解决方案也很简单。
当您的文件没有制表符时,试试这个:
sed -r 's/: +/:\t/' file.txt | expand -20
当这有效时,将输出重定向到 tmpfile 并将 tmpfile 移动到 file.txt
。