首页 > 解决方案 > 如何使用 sed 在 mac 终端中查找和替换字符串?

问题描述

我使用 Xcode。我想使用 bash 来批量修改 UI 字体。

例如改变:

<fontDescription key="fontDescription" type="system" pointSize="17"/>

至:

<fontDescription key="fontDescription" name="PingFangSC-Regular" family="PingFang SC" pointSize="12"/>`

代码开始:

 find . -type f    '(' -name '*.storyboard' -o -name '*.xib' ')' .  \
 -exec  sed -i '' s/'\<fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"\/\>'/'\<fontDescription key=\"fontDescription\" name=\"PingFangSC-Regular\" family=\"PingFang SC\" pointSize=\"12\"\/\>'/ {} +

 # placeholder, to look code better

这是简单的版本。我想找到数字(字体大小)并在下一个字符串中替换。

我已阅读使用 sed 查找和替换复杂字符串(最好使用正则表达式)

感谢@battlmonstr,我试过了

find . -type f  '(' -name '*.storyboard' -o -name '*.xib' ')' \
-exec  sed -E -i '' 's@\<fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>@<fontDescription key=\"fontDescription\" name=\"PingFangSC-Regular\" family=\"PingFang SC\" pointSize=\"12\"\/>@' {} +

#  placeholder

没关系。

为了测试更多,比如

$ echo abcd123 | sed 's/\([a-z]*\).*/\1/'
abcd

我想保留号码。

为了得到号码,然后安排内容替换,我试过了

$ echo "<fontDescription key="fontDescription" type="system" pointSize="17"/>" |  \
sed -E  's@\<fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"(\d+)\"\/>@\1@'

<fontDescription key=fontDescription type=system pointSize=17/>

结果不行,和上面的不一样。没有预期。

我在regex101中测试过,没问题。我还在想为什么。



示例内容:

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
    <device id="retina4_7" orientation="portrait">
        <adaptation id="fullscreen"/>
    </device>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--View Controller-->
        <scene sceneID="tne-QT-ifu">
            <objects>
                <viewController id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
                    <layoutGuides>
                        <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
                        <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
                    </layoutGuides>
                    <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7yI-IF-sfh">
                                <rect key="frame" x="126" y="266" width="42" height="21"/>
                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                                <fontDescription key="fontDescription" name="PingFangSC-Regular" family="PingFang SC" pointSize="12"/>
                                <nil key="textColor"/>
                                <nil key="highlightedColor"/>
                            </label>
                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vTz-nw-d8Y">
                                <rect key="frame" x="126" y="416" width="42" height="21"/>
                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                                <fontDescription key="fontDescription" name="PingFangSC-Regular" family="PingFang SC" pointSize="12"/>
                                <nil key="textColor"/>
                                <nil key="highlightedColor"/>
                            </label>
                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VCU-bo-Iyu">
                                <rect key="frame" x="175" y="218" width="42" height="21"/>
                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                                <fontDescription key="fontDescription" name="PingFangSC-Regular" family="PingFang SC" pointSize="12"/>
                                <nil key="textColor"/>
                                <nil key="highlightedColor"/>
                            </label>
                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="O3R-uM-fzi">
                                <rect key="frame" x="91" y="217" width="42" height="21"/>
                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                                <fontDescription key="fontDescription" name="PingFangSC-Regular" family="PingFang SC" pointSize="12"/>
                                <nil key="textColor"/>
                                <nil key="highlightedColor"/>
                            </label>
                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="93Z-nX-mmW">
                                <rect key="frame" x="188" y="64" width="42" height="21"/>
                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                                <fontDescription key="fontDescription" name="PingFangSC-Regular" family="PingFang SC" pointSize="12"/>
                                <nil key="textColor"/>
                                <nil key="highlightedColor"/>
                            </label>
                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9O2-dY-2nt">
                                <rect key="frame" x="277" y="197" width="42" height="13"/>
                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                                <fontDescription key="fontDescription" name="PingFangSC-Regular" family="PingFang SC" pointSize="12"/>
                                <nil key="textColor"/>
                                <nil key="highlightedColor"/>
                            </label>
                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7Mp-RI-aG9">
                                <rect key="frame" x="69" y="87" width="42" height="21"/>
                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                                <fontDescription key="fontDescription" name="PingFangSC-Regular" family="PingFang SC" pointSize="12"/>
                                <nil key="textColor"/>
                                <nil key="highlightedColor"/>
                            </label>
                        </subviews>
                        <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <gestureRecognizers/>
                        <connections>
                            <outletCollection property="gestureRecognizers" destination="QsQ-yU-xmv" appends="YES" id="4co-bU-mXm"/>
                        </connections>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
                <pongPressGestureRecognizer allowableMovement="10" minimumPressDuration="0.5" id="QsQ-yU-xmv"/>
            </objects>
            <point key="canvasLocation" x="53.600000000000001" y="26.53673163418291"/>
        </scene>
    </scenes>
</document>

标签: bashmacossed

解决方案


-i ''在您替换的第一个和第二个版本之间,-E ''可能会导致此问题。您可能想保留-i, 并-E在此之前添加如下:

sed -E -i '' ...

''是一个论点-i,基本上告诉“不要做备份”。

通常有助于找到问题的方法是将“sed”与“find”分开调试,例如单独运行该 sed 命令,无需find或无需就地替换,然后破解直到它工作。然后在顶部添加-i和。find

我建议从简单的开始,按照自己的方式前进。简化为:

sed -E 's/pointSize="12"/pointSize="15"/' 

测试它是否有效。然后稍微改进一下:

sed -E 's/pointSize="[0-9]+"/pointSize="15"/'

测试它是否有效,等等。


推荐阅读