SED 删除空格和换行符

SED 删除空格和换行符

我有以下 xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:enabled="false" android:orientation="horizontal" android:id="@id/action_container"
          android:background="@null" android:paddingLeft="4.0dip" android:layout_width="0.0dip"
          android:layout_height="48.0dip" android:layout_weight="1.0"
          style="@style/Widget.Compat.NotificationActionContainer"
          xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView android:enabled="false" android:layout_gravity="start|center" android:id="@id/action_image"
           android:layout_width="@dimen/notification_action_icon_size"
           android:layout_height="@dimen/notification_action_icon_size" android:scaleType="centerInside"
           android:alpha="0.5"/>
<TextView android:enabled="false" android:textColor="#ffcccccc" 
          android:ellipsize="end"
          android:layout_gravity="start|center" 
          android:id="@id/action_text" android:paddingLeft="4.0dip"
          android:clickable="false" android:layout_width="wrap_content" 
          android:layout_height="wrap_content"
          android:singleLine="true" android:alpha="0.5" 
          style="@style/Widget.Compat.NotificationActionText"/>
</LinearLayout>

我正在尝试删除多余的空格和换行符。

这是我需要的结果:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:enabled="false" android:orientation="horizontal" android:id="@id/action_container" android:background="@null" android:paddingLeft="4.0dip" android:layout_width="0.0dip" android:layout_height="48.0dip" android:layout_weight="1.0" style="@style/Widget.Compat.NotificationActionContainer" xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView android:enabled="false" android:layout_gravity="start|center" android:id="@id/action_image" android:layout_width="@dimen/notification_action_icon_size" android:layout_height="@dimen/notification_action_icon_size" android:scaleType="centerInside" android:alpha="0.5"/>
<TextView android:enabled="false" android:textColor="#ffcccccc" android:ellipsize="end" android:layout_gravity="start|center" android:id="@id/action_text" android:paddingLeft="4.0dip" android:clickable="false" android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" android:alpha="0.5" style="@style/Widget.Compat.NotificationActionText"/>
</LinearLayout>

我尝试使用这个命令

sed -i '' 's/^[ \t]*//;s/[ \t]*$//' file.xml

它删除了一些空格,但没有删除换行符。

最终我希望能够通过只知道它的 id(@id/action_image) 来将 ImageView 的宽度 (android:layout_width) 更改为 5dip。

我希望能够通过 id 获取 xml 元素并更改其其他参数的值

答案1

使用xmlstarlet及其fo命令:

$ xmlstarlet fo file.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:enabled="false" android:orientation="horizontal" android:id="@id/action_container" android:background="@null" android:paddingLeft="4.0dip" android:layout_width="0.0dip" android:layout_height="48.0dip" android:layout_weight="1.0" style="@style/Widget.Compat.NotificationActionContainer">
  <ImageView android:enabled="false" android:layout_gravity="start|center" android:id="@id/action_image" android:layout_width="@dimen/notification_action_icon_size" android:layout_height="@dimen/notification_action_icon_size" android:scaleType="centerInside" android:alpha="0.5"/>
  <TextView android:enabled="false" android:textColor="#ffcccccc" android:ellipsize="end" android:layout_gravity="start|center" android:id="@id/action_text" android:paddingLeft="4.0dip" android:clickable="false" android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" android:alpha="0.5" style="@style/Widget.Compat.NotificationActionText"/>
</LinearLayout>

用于xmlstarlet fo -n完全省略缩进。


要修改属性为 的节点android:layout_width的属性,绝对不需要重新格式化 XML 文档:ImageViewandroid:id@id/action_image

$ xmlstarlet ed -u '//ImageView[@android:id="@id/action_image"]/@android:layout_width' -v "5dip" file.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:enabled="false" android:orientation="horizontal" android:id="@id/action_container" android:background="@null" android:paddingLeft="4.0dip" android:layout_width="0.0dip" android:layout_height="48.0dip" android:layout_weight="1.0" style="@style/Widget.Compat.NotificationActionContainer">
  <ImageView android:enabled="false" android:layout_gravity="start|center" android:id="@id/action_image" android:layout_width="5dip" android:layout_height="@dimen/notification_action_icon_size" android:scaleType="centerInside" android:alpha="0.5"/>
  <TextView android:enabled="false" android:textColor="#ffcccccc" android:ellipsize="end" android:layout_gravity="start|center" android:id="@id/action_text" android:paddingLeft="4.0dip" android:clickable="false" android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" android:alpha="0.5" style="@style/Widget.Compat.NotificationActionText"/>
</LinearLayout>

在这里,我们用来xmlstarlet编辑我们要查找的节点的正确属性。使用 XPath 表达式选择属性

//ImageView[@android:id="@id/action_image"]/@android:layout_width

XPath 表达式中的//ImageView将会查找ImageView节点任何地方在文档内。要将其限制为仅顶级LinearLayout节点的子节点,请改用/LinearLayout/ImageView

-v "5dip"命令中的为属性赋予新值。

严格来说,这个问题说的是

我希望能够通过 id 获取 xml 元素 [...]

即,不知道节点的名称。为此,只需将ImageViewXPath 表达式更改为*.这样你就可以更新了全部android:id与给定字符串匹配的节点。

有关的:

答案2

用于awk更改分隔符并将 2 个或多个空格截断为 1 个:

$ awk -v RS="<" -v FS="\n" -v ORS="\n" -v OFS=" " '$0 {$1="<"$1; gsub(/  +/," ",$0); print}' input.xml

答案3

解决方案awk包括更改layout_width5dip

awk -v RS='> *\n *' -v ORS='>\n' '/id="@id\/action_image"/{gsub("layout_width=[^ ]*","layout_width=\"5dip\"")}NF=NF' file 

在这种特殊情况下它是有效的,但一般来说,这些标准 Linux 工具不适合处理 xml 文件。

输出:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:enabled="false" android:orientation="horizontal" android:id="@id/action_container" android:background="@null" android:paddingLeft="4.0dip" android:layout_width="0.0dip" android:layout_height="48.0dip" android:layout_weight="1.0" style="@style/Widget.Compat.NotificationActionContainer" xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView android:enabled="false" android:layout_gravity="start|center" android:id="@id/action_image" android:layout_width="5dip" android:layout_height="@dimen/notification_action_icon_size" android:scaleType="centerInside" android:alpha="0.5"/>
<TextView android:enabled="false" android:textColor="#ffcccccc" android:ellipsize="end" android:layout_gravity="start|center" android:id="@id/action_text" android:paddingLeft="4.0dip" android:clickable="false" android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" android:alpha="0.5" style="@style/Widget.Compat.NotificationActionText"/>
</LinearLayout>

答案4

您可以尝试使用以下命令删除多余的空格和空白行

sed -r "s/+//g" 文件名|sed '/^$/d'

相关内容