Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
SER1828-ZXC-A1-10002
SER1878-IOP-B1-98989
SER1930-QWE-A2-10301
SER1930-QWE-A2-10301
SER1930-QWS_GH-A2-10301
SER1930-REM_PH-A2-10301
From above data my requirement is to remove any number form eg "ZXC-A1"..
output required is
SER1828-ZXC-A-10002
SER1878-IOP-B-98989
SER1930-QWE-A-10301
SER1930-QWE-A-10301
SER1930-QWS_GH-A-10301
SER1930-REM_PH-A-10301
[I] have tried everything
... except, say:
awk -F- 'BEGIN { OFS="-" } { sub(/[0-9]/,"",$3); print }' yourdata
You should have been more clearer when you raise the problem. Do not add test cases later
You can try this, I have modified the third field to last but one. But credit to #Kaz
~> more test
SER1828-ZXC-A1-10002
SER1878-IOP-B1-98989
SER1930-QWE-A2-10301
SER1930-QWE-A2-10301
SER1930-QWS_GH-A2-10301
SER1930-REM_PH-A2-10301
SER1930-REM-SEW-PH-A2-10301
SER1940-REM-SPD-PL-D3-10301
~> awk -F- 'BEGIN { OFS="-" } { sub(/[0-9]/,"",$(NF-1)); print }' test
SER1828-ZXC-A-10002
SER1878-IOP-B-98989
SER1930-QWE-A-10301
SER1930-QWE-A-10301
SER1930-QWS_GH-A-10301
SER1930-REM_PH-A-10301
SER1930-REM-SEW-PH-A-10301
SER1940-REM-SPD-PL-D-10301
Edit
Explanation
-F- -> Define the input field separator
OFS="-" -> Set the output field separator
sub( -> Substitute
/[0-9]/ -> Select all the numbers
"" -> substitute with nothing
$(NF-1) -> For the last but one field
Print -> Print All results
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 21 days ago.
This post was edited and submitted for review 21 days ago.
Improve this question
Problem:
I have several config files (ProgramName.conf) that need to be edited with awk or sed. The first line contains several letters in place after ":" and end with "]" ProgramName. Or copy filename (it's same as ProgramName). I need to copy ProgramName to the 4th between "command=docker-compose run --rm --name" and "artisan". After conteiner name always word "artisan" in place.
Upd
Thanks for answers, problem solved!
input:
[program:ProgramName]
process_name=
directory=
command=docker-compose run --rm --name artisan some text
target output:
[program:ProgramName]
process_name=
directory=
command=docker-compose run --rm --name ProgramName artisan some text
If ed is available/acceptable, something like:
#!/bin/sh
ed -s file.txt <<-'EOF'
/^\[program:.*\]$/t/^command=/
s/^\[.*:\(.*\)\]$/ \1/
-;+j
,p
Q
EOF
In one-line
printf '%s\n' '/^\[program:.*\]$/t/^command=/' 's/^\[.*:\(.*\)\]$/ \1/' '-;+j' ,p Q | ed -s file.txt
Change Q to w if in-place editing is required.
Remove the ,p to silence the output.
gawk -i inplace '
BEGIN { RS = ORS = ""; FS = OFS = "\n" }
match($1, /^\[program:(.*)\]/, a) {
for (i = 2; i <= NF; ++i)
if ($i ~ /^command=docker-compose run --rm --name/)
$i = "command=docker-compose run --rm --name " a[1]
}
{ print $0 RT }' file
Study the GNU Awk manual for details.
I would harness GNU AWK for this task following way, let file.txt content be then
[program:ProgramName]
process_name=
directory=
command=docker-compose run --rm --name
then
awk 'BEGIN{FS="]|:|\\["}/^\[program:/{name=$3;n=NR}NR==n+3{$0=$0 " " name}{print}' file.txt
gives output
[program:ProgramName]
process_name=
directory=
command=docker-compose run --rm --name ProgramName
Explanation: I inform GNU AWK that field separator (FS) is ] or : or [ then for line starting with [program: I store third column value as name and number of row (NR) as n, then for line which is three lines after thtat happen i.e. number row equals n plus three I append space and name to line and set that as line value, for every line I print it. Be warned that it does modify
to the third line
to comply with your requirement, therefore make sure it is right place do change for all your cases.
(tested in GNU Awk 5.0.1)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I am trying to remove the text between /* and */ that is at the beginning of the file. There can be white spaces or new lines (\n) before or in-between /* and */.
I tried following but doesn't work when space or new lines are there.
sed '/^\/\*/,/\*\//d' file
Sample file:
/*******
delete
bla
***
*/
/* do not */
print "hi"
/*******
dont delete
****/
Expected output:
/* do not */
print "hi"
/*******
dont delete
****/
If ed is available.
printf '%s\n' '/^[[:space:]]*\//;/^[[:space:]]*\*\//d' ,p Q | ed -s file.txt
Change Q to w to edit the file.
Using any awk in any shell on every UNIX box, this will produce the output you want from the input you provided:
$ awk 'f; /\*\//{f=1}' file
/* do not */
print "hi"
/*******
dont delete
****/
but consider also this more general approach:
$ cat tst.awk
{ rec = (NR>1 ? rec ORS : "") $0 }
END {
$0 = rec
gsub(/#/,"#A"); gsub(/{/,"#B"); gsub(/}/,"#C")
gsub(/\/\*/,"{"); gsub(/\*\//,"}")
sub(/^[[:space:]]*{[^}]*}[[:blank:]]*\n/,"")
gsub(/}/,"*/"); gsub(/{/,"/*")
gsub(/#C/,"}"); gsub(/#B/,"{"); gsub(/#A/,"#")
print
}
.
$ awk -f tst.awk file
/* do not */
print "hi"
/*******
dont delete
****/
See https://stackoverflow.com/a/56658441/1745001 for an explanation of what those gsub()s are doing.
awk 'BEGIN{f=-1} /^ *\/\*+/{f++}f' file
/* do not */
print "hi"
/*******
dont delete
****/
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I have some trouble with this script.
#!/bin/bash
i=1
for i in $(cat rows.txt);
do
j = "$(sed -ne "$[i-1]p" LOB_final.html)"
echo $j
sed -ne "$[i-1],$[i+4]p" LOB_final.html >> ./cards/$j.txt
done;
I have an other file that contains the right row-numbers (not exactly, [row-1] is the relevant row). This row contains a string with spaces included and should be the name of the file.
Script works so far as expected, but initializing j don't work.
Does anyone have a tip?
Thank you.
EDIT: The goal was, to write any six rows (1 before and 4 after ans the given row) in a file. The file should be named with the 1 before row of the given row (a string with white spaces included).
Questions is cleared, thanks to all.
check this, have fixed quite a few issues with your script
#!/bin/bash
i=1
for i in $(cat rows.txt);
do
j="$(sed -ne "$((i-1))p" LOB_final.html)"
echo "$j"
sed -ne "$((i-1)),$((i+4))p" LOB_final.html >> ./cards/"$j".txt
done;
Removed space which was there in assigning j
$[var] replaced with $((var))
Expanded variables in double quotes
You seem to want to get the filename from line i-1 and then to store that line together with the next five lines in a file with that name.
Using awk:
awk 'NR == FNR { rows[$0]; next }
FNR + 1 in rows { name = sprintf("./cards/%s.txt", $0); left = 6 }
left > 0 { print >name; --left }' rows.txt LOB_final.html
This has been tested on some toy data, but since I don't know what your data looks like I can't say for certain that it will work without (minor) modifications.
It has the benefit that it will not parse the whole of LOB_final.html twice for each row number read from rows.txt, which your original code does. In fact, it only ever reads each file once.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
It was hard to formulate a question, better i will show example.
Txt file has these lines
city:state:address
city:state
city:
I need to extract strings where
a) only one occurrences of :
b) only one occurrences of : and has value after :
c) two occurrences of :
and put these strings to deferent files, so one file will contain all strings with
city:state:address second with city:state third one city:
Note: File has many such strings. Not obligatory to create three files in one command. It will be enough one command where i may define how many : string should contain.
Use these invocations of grep and pipe the output into different files:
grep -E "^[^:]+:\s*$" file.txt
grep -E "^[^:]+:[^:]+$" file.txt
grep -E "^[^:]+:[^:]+:.*$" file.txt
It looks for something that is not : with the regex [^:]+. It uses ^ and $ at the begin and end to match the whole input line.
This is a job for awk, not grep. All you need is:
awk -F':' '
NF==3 { print > "file_c"; next }
{ print > ($2=="" ? "file_a" : "file_b") }
' file
and that'll create all the files you want in one pass of your input file.
If you have more fields and more rules just write them all down so they're mutually exclusive, e.g. you could implement the above as:
NF==3 { print > "file_c" }
NF==2 && $2=="" { print > "file_a" }
NF==2 && $2!="" { print > "file_b" }
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
A B 5 C Hello: XYZ 'Main Search String', Searching In: '[Name] = "I just want this" AND [State] = Active ('NAME', 'ACT')
How to extract this string: I just want this
grep "Main Search String" filename | awk -F"tab" '{print $6}' | ??
Using awk
awk -F\" '/Main Search String/ {print $2}' file
I just want this
using grep
grep -Po "\[Name\] = \"\K[^\"]*" file
grep -Po "(?<=\[Name\] = \")[^\"]*" file
sed -n 's/.*\[Name\] = "\([^"]*\)".*/\1/p' YourFile
assuming the content is betwween " and for the tag [Name] on any line of your input file
If you want more fun :)
$ cat /tmp/delme
A B 5 C Hello: XYZ 'Main Search String', Searching In: '[Name] = "I just want this" AND [State] = Active ('NAME', 'ACT')
$ cat /tmp/delme | perl -e 'while (<>) { if ( /.*[Name] = \"(.*)\"/ ) { print "$1\n"; } };'
I just want this
With this you can use the whole regex and pattern match things provided by perl...and perl is on almost every system as I know.Give it a try! ;)
EDITED for pattern found case:
$ cat /tmp/delme | perl -e 'while (<>) { print "TEXT: ";print; if ( /.*Main Search String.*\[Name] = "(.*)\"/ ) { print "RESULT: $1\n"; } };'
TEXT: A B 5 C Hello: XYZ 'Main Search String', Searching In: '[Name] = "I just want this" AND [State] = Active ('NAME', 'ACT')
RESULT: I just want this
TEXT: A B 5 C Hello: XYZ 'Not Search String', Searching In: '[Name] = "I just want this" AND [State] = Active ('NAME', 'ACT')
Got it in 13 characters plus the file name:
cut -d\" -f 2 text.txt
This command cuts the text into columns separated by the double-quotes. (-d\") That creates three columns. It prints out the second column with your answer (-f 2).
Like Lutz Horn said, you need to provide a bigger data set to test any of these commands. Many of them will fail if they do not represent the complete pattern they need to parse.