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_widthXML 문서의 형식을 다시 지정할 필요가 전혀 없습니다.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'

관련 정보