I’m trying to find a line in a yml configuration file and replace the next line with a specific value. I tried sed, but it seems it is not replacing or not able to find the pattern. Below is the snippit of that yml file
applicationConnectors: - type: http port: 14080 bindHost: 15.213.48.154 headerCacheSize: 512 bytes outputBufferSize: 32KiB maxRequestHeaderSize: 8KiB maxResponseHeaderSize: 8KiB inputBufferSize: 8KiB idleTimeout: 30 seconds minBufferPoolSize: 64 bytes bufferPoolIncrement: 1KiB maxBufferPoolSize: 64KiB acceptorThreads: 1 selectorThreads: 2 acceptQueueSize: 1024 reuseAddress: true useServerHeader: false useDateHeader: true useForwardedHeaders: true adminConnectors: - type: http port: 14180
I want to change port value to 14081 for applicationConnectors as there is another port exists for adminConnectors After the script execution it should look like:
applicationConnectors: - type: http port: 14081 bindHost: 15.213.48.154 headerCacheSize: 512 bytes outputBufferSize: 32KiB maxRequestHeaderSize: 8KiB maxResponseHeaderSize: 8KiB inputBufferSize: 8KiB idleTimeout: 30 seconds minBufferPoolSize: 64 bytes bufferPoolIncrement: 1KiB maxBufferPoolSize: 64KiB acceptorThreads: 1 selectorThreads: 2 acceptQueueSize: 1024 reuseAddress: true useServerHeader: false useDateHeader: true useForwardedHeaders: true adminConnectors: - type: http port: 14180
I have tried below code:
var1="14081" var2="port" sed '/applicationConnectors:/{n;s/($var2).*$/1${var1}/}' configuration.yml > newfile mv newfile configuration.yml
but it seems this code is not replacing anything.
Advertisement
Answer
sed is best for s/old/new, that is all. For anything else just use awk for clarity, portability, robustness, etc. Look:
$ awk -v rec='applicationConnectors' -v tag='port' -v val='14081' ' /^ [^ ]/{name=$1} name==(rec":") && $1==(tag":"){sub(/[^ ]+$/,""); $0=$0 val} 1' file applicationConnectors: - type: http port: 14081 bindHost: 15.213.48.154 headerCacheSize: 512 bytes outputBufferSize: 32KiB maxRequestHeaderSize: 8KiB maxResponseHeaderSize: 8KiB inputBufferSize: 8KiB idleTimeout: 30 seconds minBufferPoolSize: 64 bytes bufferPoolIncrement: 1KiB maxBufferPoolSize: 64KiB acceptorThreads: 1 selectorThreads: 2 acceptQueueSize: 1024 reuseAddress: true useServerHeader: false useDateHeader: true useForwardedHeaders: true adminConnectors: - type: http port: 14180
Want to change acceptQueueSize:
to 17
instead? It’s the same script with just different variable values:
$ awk -v rec='applicationConnectors' -v tag='acceptQueueSize' -v val='17' ' /^ [^ ]/{name=$1} name==(rec":") && $1==(tag":"){sub(/[^ ]+$/,""); $0=$0 val} 1' file applicationConnectors: - type: http port: 14080 bindHost: 15.213.48.154 headerCacheSize: 512 bytes outputBufferSize: 32KiB maxRequestHeaderSize: 8KiB maxResponseHeaderSize: 8KiB inputBufferSize: 8KiB idleTimeout: 30 seconds minBufferPoolSize: 64 bytes bufferPoolIncrement: 1KiB maxBufferPoolSize: 64KiB acceptorThreads: 1 selectorThreads: 2 acceptQueueSize: 17 reuseAddress: true useServerHeader: false useDateHeader: true useForwardedHeaders: true adminConnectors: - type: http port: 14180
Only try that with your currently accepted sed
solution if you enjoy counting n
s :-). Note also that this will work no matter what order the lines appear within each record since it keys off the name port
rather than assuming that will appear some specific number of lines after applicationConnectors:
. Finally, this will work even if the strings you’re searching for or replacing with contain RE metachars (e.g. .
), backreference chars (e.g. 1
or &
), or sed delimiters (e.g. /
).