web-dev-qa-db-ja.com

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

一部のスペースは削除されましたが、改行は削除されませんでした。

最終的には、たとえばImageViewの幅(Android:layout_width)を、そのid(@ id/action_image)だけを知って5dipに変更できるようにしたいと思います。

iDでxml要素を取得し、他のパラメーターの値を変更できるようにしたい

2
אVי

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属性がAndroid:idであるImageViewノードの@id/action_image属性を変更するには、XMLドキュメントを再フォーマットする必要はありません。

$ 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ノードanywhereを検索します。トップレベルのLinearLayoutノードの子ノードのみに制限するには、代わりに/LinearLayout/ImageViewを使用します。

コマンドの-v "5dip"は、属性に新しい値を与えます。

厳密に言えば、質問は言う

iDでxml要素を取得できるようにしたい[...]

つまり、ノードの名前を知らなくても。これを行うには、XPath式のImageView*に変更するだけです。そうすれば、Android:idが指定された文字列と一致するallノードを更新します。

関連:

3
Kusalananda

この制限されたhtmlコードの簡単なハックの1つは、次のとおりです。

$ Perl -F'(?m:^<|>$)' -0777 -ane '
   pop @F;
   print $_, qw[< >][$|--] for map { s/\n\h+/ /gr } @F;
   print "\n";
 ' input.html

出力:

<?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エディターを使用して、同じことを実行することもできます。

$ sed -e '
   /^<.*>$/b
   /^</,/\/\{0,1\}>$/!b
   H;/^</h;/\/\{0,1\}>$/!d;g
   s/[[:blank:]]*\n[[:blank:]]*/ /g
 ' input.html
0
Rakesh Sharma

awkを使用して区切り文字を変更し、2つ以上の空白を1つに切り捨てます。

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

layout_widthから5dipへの変更を含むawkソリューション:

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>
0
jimmij