For integration tests, I have output that contains full file paths. I want to have my test script replace the user-specific start of the file path (e.g. /Users/uli/) with a generic word (USER_DIR) so that I can compare the files.
The problem, of course, are the slashes in the path. I tried the solutions given here and here, but they don't work for me:
#!/bin/bash
old_path="/Users/uli/"
new_path="USERDIR"
sed -i "s#$old_path#$new_path#g" /Users/uli/Desktop/replacetarget.txt
I get the error
sed: 1: "/Users/uli/Desktop/repl ...": invalid command code u
This is the version of sed that comes with macOS 10.14.6 (it has no --version option and is installed in /usr/bin/, so no idea what exact version).
Update:
I also tried
#!/bin/bash
old_path="/Users/uli/"
old_path=${old_path//\//\\\/}
new_path="USERDIR"
regex="s/$old_path/$new_path/g"
echo $old_path
echo $regex
sed -i $regex /Users/uli/Desktop/replacetarget.txt
But I get the same error. What am I doing wrong?
BSD sed requires an argument following -i (the empty string '' indicates no backup, similar to argumentless -i in GNU sed). As a result, your script is being treated as the backup-file extention, and your input file as the script.
old_path="/Users/uli/"
new_path="USERDIR"
sed -i '' "s#$old_path#$new_path#g" /Users/uli/Desktop/replacetarget.txt
However, sed is a stream editor, based on the file editor ed, so using -i is an indication you are using the wrong tool to begin with. Just use ed.
old_path="/Users/uli/"
new_path="USERDIR"
printf 's#%s#%s#g\nwq\n' "$old_path" "$new_path" | ed /Users/uli/Desktop/replacetarget.txt
Obligatory warning: neither editor is parameterized as such; you are simpling generating the script dynamically, which means it's your responsibility to ensure that the resulting script is valid. (For example, if either parameter contains a ;, it had better be escaped to prevent (s)ed from seeing it as a command separator.)
string='binddn:cn=SxX.UXxxxM-E2A,OU=CA,OU=AI INFRASTRUCTURE,DC=i,DC=companyname,DC=com'
The working peice of code in Red Hat
dn=($(grep -oi 'cn=[^():]*dc=com' <<< "$string"))
I modified the code for AIX and modified code is
dn=($(grep -xi 'cn=[^():]*dc=com' "$string"))
The code is working perfect in RedHat server, the output in redhat is
dn[0]="cn=SxX.UXxxxM-E2A,OU=CA,OU=AI INFRASTRUCTURE,DC=i,DC=companyname,DC=com"
The error in AIX is
grep: can't open binddn:cn=SxX.UXxxxM-E2A,OU=CA,OU=AI INFRASTRUCTURE,DC=i,DC=companyname,DC=com
Edited:
Another example:
string = "userbasedn:DC=i,DC=companyname,DC=com?subtree?(&(objectcategory=person)(uidNumber=*)(|(memberOf:1.2.840.113556.1.4.1941:=cn=example1,OU=GROUPS,OU=AI INFRASTRUCTURE,DC=i,DC=companyname,DC=com)(memberOf:1.2.840.11.1.4.1941:=cn=example2,OU=GROUPS,OU=AI INFRASTRUCTURE,DC=i,DC=companyname,DC=com)))
groupbasedn:DC=i,DC=companyname,DC=com?subtree?(&(objectcategory=group)(gidNumber=*))"
expected output
dn[0]=cn=example1,OU=GROUPS,OU=AI INFRASTRUCTURE,DC=i,DC=companyname,DC=com
dn[1]=cn=example2,OU=GROUPS,OU=AI INFRASTRUCTURE,DC=i,DC=companyname,DC=com
If you can use awk, try this:
echo "$string" | awk -F"cn=" 'NF>1{$0=tolower($0);for (i=2;i<=NF;i++) {split($i,a,"dc=com)");print FS a[1]"dc=com"}}'
cn=example1,ou=groups,ou=ai infrastructure,dc=i,dc=companyname,dc=com
cn=example2,ou=groups,ou=ai infrastructure,dc=i,dc=companyname,dc=com
The second argument to grep is a file name, not a string. AIX correctly reports that it cannot find a file with that name. You would get the same error on Red Hat if you tried the same command.
Unfortunately, the -x option doesn't do what you hope; it checks whether the entire line of input matches the regex. Again, you will find exactly the same behavior on Red Hat.
According to the AIX grep manual page it supports the -o option just fine, though.
The Bash "here string" syntax <<<"string" is not available if you don't have Bash, but it is easy to rephrase portably:
printf '%s\n' "$string" |
grep -oi 'cn=[^():]*dc=com'
If you don't have grep -o, try with sed:
printf '%s\n' "$string" |
sed -n 's/.*\(cn=[^():]*dc=com\).*/\1/p'
This is not exactly the same, because the first .* is greedy. If you expect more than one match on a line, you will need a slightly more complex regex.
On ubuntu I'm running a console perl replace on a csv file of ~500MB. This is the call:
perl -i -pe 's/AS100\n/AS100/g' test.csv
Before run it on the complete file, I extracted a subset of it of ~30MB and run this script successfully.
When running on the full file, no substitution is done, and no error or message is showed.
I've tried also with sed, but the behavior is the same.
How can I solve this issue?
Thank you
If you have room, try to do this instead to look at the substitution as it is done to another file:
perl -pe 's/AS100\n/AS100/g' test.csv | tee > test2.csv
My question is though, is it only the rows ending with AS100 that needs the newline removal?
After trying everything, I found out that in the original file the pattern was:
As100\r
and that the \n was a conversion done by Sublime Text when saving the test file.
So the correct code to do the trick was:
perl -i -pe 's/AS100\r/AS100/g' test.csv
The file that I want to grep contains many lines.
I want to grep lines which contain only 1 digit: "0" or "1".
I used this command:
exec grep -e "^\[0-1\]{1}$" file
But I got:
child process exited abnormally
What's wrong with RegExp of grep?
The most common issue when running grep as a Tcl subprocess is that it exits with a non-zero error code when it doesn't find anything at all. This always causes Tcl to throw an exception. The simplest workaround is perhaps this:
exec /bin/sh -c {grep -e '^[0-1]{1}$'; true} < file
Note that we are feeding in the file using a redirection here; this means that it is not necessary to strip the name of the file from the results.
I am trying to search string and replace string in a file. I used the below code:
sed -e 's/{"AP_SESSION_ID"\1\"787"}/{"AP_SESSION_ID"\1\"800"}/g' FILE|tee FILE
but it is not working and the output is like this:
sed: number in \[0-9] invalid
My environment is CYGWIN.
sample file is:
DP_SESSION_ID is a sting for values
DP_SESSION_ID is aplicat
"DP_S42SETTACC_TYPE"\1\"02"
"DP_SAP_CLIENT"\1\"460"
"DP_SAP_COMM_CONNECTION"\1\"JAVA_COMM_TOOL_ANALYZER"
"DP_SAP_CONNECTION"\1\"JAVA_TOOL_ANALYZER"
"DP_SAP_TOOLBI_CONNECTION"\1\"JAVA_TOOLBI_ANALYZER"
"DP_SESSION_ID"\1\"808"
I want search this "DP_SESSION_ID"\1\" sting and replace corresponding number like 808 in file prenatally(windows env), and i wand sing line command in windows bat command or perl command i don't want scrip or program
even i have installed cygwin tool in my server so unix also ok but single line command
server: windows 2008,cygwin x
using tool : datastage server jobs
perl -pi -e 's{" "DP_SESSION_ID"\1\"808 '"}{' "DP_SESSION_ID"\1\"900 '"'"}g' " file name
this code is not working
Please give good solution
You need to "escape" the backslashes by using two in a row:
sed -e 's/{"AP_SESSION_ID"\\1\\"787"}/{"AP_SESSION_ID"\\1\\"800"}/g' FILE|tee FILE
Otherwise the \1 is treated as a backreference, and you have no subgroups (parenthesized expressions) to reference.
Apart from back-slashes, IMO you also need to escape the quotes.
sed -e 's/{\"AP_SESSION_ID\"\\1\\\"787\"}/{\"AP_SESSION_ID\"\\1\\\"800\"}/g' FILE|tee FILE