linux replace string with another string - linux

I want to replace a string in a file.
I have a textfile which looks like this: id#string.
123456#some new string
234567#some other new string
345678#still some other new string
and then I have alot of folders based on the id of the textfile.
so now I want to replace the string in a textfile
{"fields":[{"t":"B","v":"false or true","n":"SomeText"},{"t":"S","v":"","n":"Keywords"},{"t":"S","v":"","n":"Author"},{"t":"S","v":"","n":"SomeText"},{"t":"S","v":"THI$ is THE old §TRING I want to REPLACE","n":"SomeText"},{"t":"S","v":"","n":"SomeText"},{"t":"A","n":"SomeText"},{"t":"A","v":"SomeInt","n":"SomeText"}]}
but i dont know how to do this since the newstring and or oldstring may contain additional characters
#!/bin/bash
FOLDER=`echo 123456#string | cut -d# -f1`
NEWSTRING=`echo 123456#string | cut -d# -f2`
sed -i ??? $FOLDER/filename.txt
thanks for your help

of the issue is not clear what should be engaged and what replaced, but maybe you need is:
#!/bin/bash
#
# t1 file contains your strings
#
ROW='{"fields":[{"t":"B","v":"false or true","n":"SomeText"},{"t":"S","v":"","n":"Keywords"},{"t":"S","v":"","n":"Aut
IFS=$'\n'
for S in $(cat ./t1); do
F=$(echo $S | awk -F# '{print $1}')
N=$(echo $S | awk -F# '{print $2}')
if [ -z "$N" ]; then continue; fi
NROW=$(echo ${ROW/THIS is THE old STRING I want to REPLACE/$S})
NROW=$(echo ${NROW/Keywords/$N})
NROW=$(echo ${NROW/false or true/$F})
#mkdir $F
#echo $NROW >> file.json
echo $NROW
done

Related

Unix Script loop through individual variables in a list and execute code

I have been busting my head all day long without coming up with a sucessfull solution.
Setup:
We have Linux RHEL 8.3 and a file, script.sh
There is an enviroment variable set by an application with a dynamic string in it.
export PROGARM_VAR="abc10,def20,ghi30"
The delimiter is always "," and the values inside vary from 1 to 20.
Inside the script I have defined 20 variables which take the values
using "cut" command I take each value and assign it to a variable
var1=$(echo $PROGARM_VAR | cut -f1 -d,)
var2=$(echo $PROGARM_VAR | cut -f2 -d,)
var3=$(echo $PROGARM_VAR | cut -f3 -d,)
var4=$(echo $PROGARM_VAR | cut -f4 -d,)
etc
In our case we will have:
var1="abc10" var2="def20" var3="ghi30" and var4="" which is empty
The loop must take each variable, test if its not empty and execute 10 pages of code using the tested variable. When it reaches an empty variable it should break.
Could you give me a hand please?
Thank you
Just split it with a comma. There are endless possibilities. You could:
10_pages_of_code() { echo "$1"; }
IFS=, read -a -r vars <<<"abc10,def20,ghi30"
for i in "${vars[#]}"; do 10_pages_of_code "$i"; done
or:
printf "%s" "abc10,def20,ghi30" | xargs -n1 -d, bash -c 'echo 10_pages_of_code "$1"' _
A safer code could use readarray instead of read to properly handle newlines in values, but I doubt that matters for you:
IFS= readarray -d , -t vars < <(printf "%s" "abc10,def20,ghi30")
You could also read in a stream up:
while IFS= read -r -d, var || [[ -n "$var" ]]; do
10_pages_of_code "$var"
done < <(printf "%s" "abc10,def20,ghi30")
But still you could do it with cut... just actually write a loop and use an iterator.
i=0
while var=$(printf "%s\n" "$PROGARM_VAR" | cut -f"$i" -d,) && [[ -n "$var" ]]; do
10_pages_of_code "$var"
((i++))
done
or
echo "$PROGRAM_VAR" | tr , \\n | while read var; do
: something with $var
done

How to search and delete a pattern from a line?

I need to write a simple bash script that takes a text line
some-pattern something-else
and erases some-pattern and returns only something-else. I wrote a script to do the opposite with grep -o, but I don't know how I could do with this case. Any help is very much appreciated.
sample input:
"SNMPv2::sysLocation.0 = STRING: someLocation"
Desired Output:
"someLocation"
Considering " are NOT in your sample Input_file and expected output, could you please try following with GNU grep.
grep -oP '.*STRING: \K(.*)' Input_file
someLocation
For \K explanation:
\K is a PCRE extension to regex syntax discarding content prior to
that point from being included in match output
You can use sed to delete the part in front of what you want to keep.
Given:
$ echo "$s"
"SNMPv2::sysLocation.0 = STRING: someLocation"
You can do:
$ echo "$s" | sed -nE 's/^.*(someLocation)/\1/p'
someLocation
And if you want to add quotes:
$ echo "$s" | sed -nE 's/^.*(someLocation)/"\1"/p'
"someLocation"
If the portion after STRING: is variable, not fixed, you can use STRING: and the capture anchor:
$ echo "$s" | sed -nE 's/^.*STRING:[[:space:]]*(.*)/"\1"/p'
"someLocation"
Or, sed to capture and print the last word after the last space:
$ echo "$s" | sed -nE 's/([^[:space:]]*$)/\1/p'
You can also use awk if the last word is space separated from the other fields:
$ echo "$s" | awk '{print $NF}'
Or a pipeline with cut and rev works too:
$ echo "$s" | rev | cut -d' ' -f 1 | rev
You can use: echo ${STRING} | awk -F" " '/someLocation/ { print $NF }'
-F will use space (represented by double-quotes with space between them) as separator; /someLocation/ will search for your location; { print $NF } will show the last part of your string (which, I believe, is the place where location is.

Linux Shell Script: extract values from string in specified manner

I have one variable contain values like:
USER1:USER2,USER3:USER4,USER5:USER6
I want to extract values like USER1,USER3,USER5
For Example:
VALUE = USER1:USER2,USER3:USER4,USER5:USER6
how I echo to extract like this
USER1,USER3,USER5
#!/bin/bash
string=USER1:USER2,USER3:USER4,USER5:USER6
IFS=', ' read -r -a array <<< "$string"
output=
for kv in ${array[#]}; do
key=$(echo $kv | cut -d':' -f1)
output="$output,$key"
done
output=$(echo $output | cut -c 2-)
echo $output

How to use uniq after printf

I have lot of file which I need to concatenate together with same prefix. I have an idea, but I do not know how to solve this problem:
files:
NAME1_C001_xxx.tsv
NAME1_C001_yyy.tsv
NAME2_C001_xxx.tsv
NAME2_C001_yyy.tsv
I want to print just uniq prefix - NAME1 and NAME2. Length of string in prefix and suffix is vary, but always before prefix is _C001
my solution is:
fo i in *.tsv
do prexix=$(printf "%s\n" "${i%_C001*}")
cat $prefix_C001_xxx.tsv $prefix_C001_yyy.tsv > ${i%_C001*}.merged.tsv
done;
But this solution is not very good. I have each prefix twice.
Thank you for any help.
EDITED:
One solution thanks to anubhava:
fo i in $(printf "%s\n" *.tsv | awk -F '_C001' '!seen[$1]++{print $1}')
do
cat $prefix_C001_xxx.tsv $prefix_C001_yyy.tsv > ${i%_C001*}.merged.tsv
done;
You don't need printf at all here; it's just an unnecessary wrapper around the parameter substitution you are already using.
for i in *.tsv
do prefix=${i%_C001*}
[[ -f $prefix.merged.tsv ]] && continue # Avoid doing the same prefix twice
cat "${prefix}"_* > "$prefix.merged.tsv"
done
As your filenames don't contain any newline you can pipe your list to a awk command to print unique prefixes using field separator as _C001:
printf "%s\n" *.tsv | awk -F '_C001' '!seen[$1]++{print $1}'
NAME1
NAME2
You can also use _ as FS in awk:
printf "%s\n" *.tsv | awk -F _ '!seen[$1]++{print $1}'

Linux - Find a string and get the next section

If I have a string like "name":"tempname","department":"tempdept", I want to search for the value for "department" which is "tempdept". So if "department" exists, I need just the value returned. The length of the string that is searched can be very long. Is this possible using sed/awk, can you please help?
I tried the following, but it returns the whole string. I am searching for department here.
echo $data | sed 's/\(\"department\":\)\(.*\"\)/\2/'
Some simple solutions:
echo "$data" | tr , \\n | awk -F: '$1 ~ /^department$/{ print $2 }'
or
echo "$data" | awk -F: '$1 ~ /^department$/{ print $2 }' RS=,
Your solution just need minor modifications:
echo "$data" | tr , \\n | sed -n 's/"department":\(.*\)/\2/p'
or
echo "$data" | tr , \\n | sed -n '/"department":/s///p'
See if this does it for you:
sed -ne '/"department"/{s/^.*"department":"\([^"]*\).*/\1/;p;}'
Example:
echo '"name":"tempname","department":"tempdept"' | sed -ne '/"department"/{s/^.*"department":"\([^"]*\).*/\1/;p;}'
tempdept
If you need to retain the double quotes, just add them back in during the replacement:
sed -ne '/"department"/{s/^.*"department":"\([^"]*\).*/"\1"/;p;}

Resources